도큐먼트 삽입
insertOne
도큐먼트를 삽입하려면 컬렉션의 insertOne 메서드를 사용한다.
> db.loginLogs.insertOne({name: "devbeekei", loginDate: new Date()})
{
"acknowledged" : true,
"insertedId" : ObjectId("628f19887a32d396cf84a7e7")
}
> db.loginLogs.findOne({name: "devbeekei"})
{
"_id" : ObjectId("628f19887a32d396cf84a7e7"),
"name" : "devbeekei",
"loginDate" : ISODate("2022-05-26T06:09:12.597Z")
}
도큐먼트에 "_id"키가 추가되고 도큐먼트가 몽고DB에 저장된다.
insertMany
여러 도큐먼트를 컬렉션에 삽입하려면 insertMany로 도큐먼트 배열을 데이터베이스에 전달한다.
각 도큐먼트마다 데이터베이스에 저장되는 것이 아닌 한 번에 대량 삽입하므로 여러 도큐먼트를 삽입할 때 훨씬 더 효율적이다.
> db.loginLogs.drop()
true
> db.loginLogs.insertMany([
... { name: "devbeekei", date: new Date()},
... { name: "hongGilDong", date: new Date()},
... { name: "son", date: new Date()},
... ])
{
"acknowledged" : true,
"insertedIds" : [
ObjectId("628f1a667a32d396cf84a7e8"),
ObjectId("628f1a667a32d396cf84a7e9"),
ObjectId("628f1a667a32d396cf84a7ea")
]
}
> db.loginLogs.find()
{ "_id" : ObjectId("628f1a667a32d396cf84a7e8"), "name" : "devbeekei", "date" : ISODate("2022-05-26T06:12:54.200Z") }
{ "_id" : ObjectId("628f1a667a32d396cf84a7e9"), "name" : "hongGilDong", "date" : ISODate("2022-05-26T06:12:54.200Z") }
{ "_id" : ObjectId("628f1a667a32d396cf84a7ea"), "name" : "son", "date" : ISODate("2022-05-26T06:12:54.200Z") }
수십, 수백, 수천 개의 도큐먼트를 한 번에 전송하면 도큐먼트 삽입이 매우 빨라진다.
한 번에 일괄 삽입할 수 있는 데이터의 크기에는 제한이 있는데, 이 제한된 크기보다 큰 삽입을 시도하면 제한된 크기만큼 분할하여 삽입된다.
insertMany를 사용할 때 만약 중간에 삽입되는 도큐먼트에 오류가 발생하게 되면 정렬 연산에 경우에는 해당 오류가 발생하는 도큐먼트부터는 삽입되지 않는다.
정렬 또는 비정렬 연산의 선택은 두 번째 매개변수로 {ordered: true or false}로 지정할 수 있다.(default는 정렬 연산)
> db.loginLogs.drop()
true
> db.loginLogs.insertMany([
{ _id: 0, name: "devbeekei", date: new Date()},
{ _id: 1, name: "devbeekei", date: new Date()},
{ _id: 2, name: "devbeekei", date: new Date()},
{ _id: 2, name: "devbeekei", date: new Date()},
{ _id: 3, name: "devbeekei", date: new Date()}
])
BulkWriteError({
"writeErrors" : [
{
"index" : 3,
"code" : 11000,
"errmsg" : "E11000 duplicate key error collection: test.loginLogs index: _id_ dup key: { _id: 2.0 }",
"op" : {
"_id" : 2,
"name" : "devbeekei",
"date" : ISODate("2022-05-26T07:01:55.707Z")
}
}
],
"writeConcernErrors" : [ ],
"nInserted" : 3,
"nUpserted" : 0,
"nMatched" : 0,
"nModified" : 0,
"nRemoved" : 0,
"upserted" : [ ]
})
> db.loginLogs.find()
{ "_id" : 0, "name" : "devbeekei", "date" : ISODate("2022-05-26T07:01:55.707Z") }
{ "_id" : 1, "name" : "devbeekei", "date" : ISODate("2022-05-26T07:01:55.707Z") }
{ "_id" : 2, "name" : "devbeekei", "date" : ISODate("2022-05-26T07:01:55.707Z") }
_id를 중복으로 삽입해 일부러 오류를 발생시켰을 때 정렬 연산에 경우 오류가 발생하기 전의 도큐먼트만 삽입된 것을 확인할 수 있다.
이번엔 비정렬 연산으로 insertMany를 시도해보자.
> db.loginLogs.drop()
true
> db.loginLogs.insertMany([
{ _id: 0, name: "devbeekei", date: new Date()},
{ _id: 1, name: "devbeekei", date: new Date()},
{ _id: 2, name: "devbeekei", date: new Date()},
{ _id: 2, name: "devbeekei", date: new Date()},
{ _id: 3, name: "devbeekei", date: new Date()}
], {ordered: false})
BulkWriteError({
"writeErrors" : [
{
"index" : 3,
"code" : 11000,
"errmsg" : "E11000 duplicate key error collection: test.loginLogs index: _id_ dup key: { _id: 2.0 }",
"op" : {
"_id" : 2,
"name" : "devbeekei",
"date" : ISODate("2022-05-26T07:03:40.285Z")
}
}
],
"writeConcernErrors" : [ ],
"nInserted" : 4,
"nUpserted" : 0,
"nMatched" : 0,
"nModified" : 0,
"nRemoved" : 0,
"upserted" : [ ]
})
> db.loginLogs.find()
{ "_id" : 0, "name" : "devbeekei", "date" : ISODate("2022-05-26T07:04:17.889Z") }
{ "_id" : 1, "name" : "devbeekei", "date" : ISODate("2022-05-26T07:04:17.889Z") }
{ "_id" : 2, "name" : "devbeekei", "date" : ISODate("2022-05-26T07:04:17.889Z") }
{ "_id" : 3, "name" : "devbeekei", "date" : ISODate("2022-05-26T07:04:17.889Z") }
비정렬 연산으로 insertMany를 실행한 결과 오류가 발생산 도큐먼트를 제외하고 모두 삽입된 것을 확인할 수 있다.
삽입 유효성 검사
몽고DB는 삽입된 데이터에 최소한의 검사를 수행한다.
도큐먼트의 기본 구조를 검사해 _id 필드가 존재하지 않으면 새로 추가하고, 모든 도큐먼트는 16메가바이트보다 작아야 한다.
Object.bsonsize({ ... }) 함수를 실행하면 Binary JSON(BSON) 크기(바이트 단위)를 확인할 수 있다.
> car={brand: "kia", name: "Sportage"}
{ "brand" : "kia", "name" : "Sportage" }
> Object.bsonsize(car)
39
이는 대개 나쁜 스키마 설계를 예방하고 일관된 성능을 보장한다.
최소한의 검사를 하는 이유는 유효하지 않은 데이터가 입력되기 쉽기 때문이다.
그러므로 애플리케이션 서버와 같은 신뢰성 있는 소스만 데이터베이스에 연결해야 한다.
삽일할 도큐먼트가 너무 크지 않은지, UTF-8이 아닌 문자열을 쓰는지, 인식할 수 없는 데이터형을 포함하는지 등을 확인해야 한다.
도큐먼트 삭제
몽고DB CRUD API는 deleteOne과 deleteMany를 제공한다.
두 메서드 모두 필터 도큐먼트를 첫 번째 매개변수로 사용한다.
deleteOne
deleteOne은 필터와 일치하는 첫 번째 도큐먼트를 삭제한다.
어떤 도큐먼트가 먼저 발견되는지는 도큐먼트가 삽입된 순서, 도큐먼트에 어떤 갱신이 이뤄졌는지(일부 스토리지 엔진의 경우), 어떤 인덱스를 지정하는지 등 몇 가지 요인에 따라 결정된다.
> db.cars.find()
{ "_id" : ObjectId("628f2e8b7a32d396cf84a7eb"), "name" : "avante", "brand" : "hyundai" }
{ "_id" : ObjectId("628f2e8b7a32d396cf84a7ec"), "name" : "k5", "brand" : "kia" }
{ "_id" : ObjectId("628f2e8b7a32d396cf84a7ed"), "name" : "sportage", "brand" : "kia" }
{ "_id" : ObjectId("628f2e8b7a32d396cf84a7ee"), "name" : "tivoli", "brand" : "ssangyong" }
> db.cars.deleteOne({ name: "avante" })
{ "acknowledged" : true, "deletedCount" : 1 }
> db.cars.find()
{ "_id" : ObjectId("628f2e8b7a32d396cf84a7ec"), "name" : "k5", "brand" : "kia" }
{ "_id" : ObjectId("628f2e8b7a32d396cf84a7ed"), "name" : "sportage", "brand" : "kia" }
{ "_id" : ObjectId("628f2e8b7a32d396cf84a7ee"), "name" : "tivoli", "brand" : "ssangyong" }
deleteMany
필터와 일치하는 모든 도큐먼트를 삭제하려면 deleteMany를 사용한다.
> db.cars.find()
{ "_id" : ObjectId("628f2e8b7a32d396cf84a7eb"), "name" : "avante", "brand" : "hyundai" }
{ "_id" : ObjectId("628f2e8b7a32d396cf84a7ec"), "name" : "k5", "brand" : "kia" }
{ "_id" : ObjectId("628f2e8b7a32d396cf84a7ed"), "name" : "sportage", "brand" : "kia" }
{ "_id" : ObjectId("628f2e8b7a32d396cf84a7ee"), "name" : "tivoli", "brand" : "ssangyong" }
> db.cars.deleteMany({brand: "kia"})
{ "acknowledged" : true, "deletedCount" : 2 }
> db.cars.find()
{ "_id" : ObjectId("628f2e8b7a32d396cf84a7eb"), "name" : "avante", "brand" : "hyundai" }
{ "_id" : ObjectId("628f2e8b7a32d396cf84a7ee"), "name" : "tivoli", "brand" : "ssangyong" }
drop
컬렉션의 모든 도큐먼트를 제거할 때는 drop을 사용한다.
> db.cars.drop()
true
> db.cars.find()
일반적으로 도큐먼트를 제거하는 deleteMany는 꽤 빠르다.
그러나 전체 컬렉션을 삭제하려면 다음과 같이 drop을 사용하는 편이 더 빠르다.
데이터는 한 번 제거하면 영원히 삭제된다.
이전에 백업된 데이터를 복원하는 방법 외에 delete 또는 drop 작업을 취소하거나 삭제된 도큐먼트를 복구하는 방법은 없다.
'MongoDB' 카테고리의 다른 글
몽고DB 배열 연산자 소개 및 사용법 (0) | 2022.06.03 |
---|---|
몽고DB 도큐먼트 갱신, 치환하기 (0) | 2022.06.03 |
몽고DB 셸 사용해보기 (0) | 2022.05.26 |
몽고DB의 데이터형 (0) | 2022.05.25 |
몽고DB 셸 소개 (0) | 2022.05.25 |