MongoDB 프로젝트 중첩 필드
- MongoDB 프로젝트 중첩 필드
-
$project
집계 단계를 사용하여 MongoDB에서 중첩 필드 프로젝트 -
$unset
집계 단계를 사용하여 MongoDB에서 지정된 필드를 제외한 중첩 필드 가져오기 -
forEach()
루프를 사용하여 MongoDB에서 중첩 필드 가져오기 -
mapReduce()
메서드를 사용하여 MongoDB에서 중첩 필드 투영
오늘은 $project
및 $unset
집계 단계, forEach()
루프 및 mapReduce()
메서드를 사용하여 MongoDB에서 데이터를 쿼리하는 동안 중첩 필드를 투영하는 방법을 배웁니다.
MongoDB 프로젝트 중첩 필드
MongoDB에서는 find()
메소드를 사용하여 모든 문서를 검색할 수 있지만 특정 중첩 필드에만 액세스하려는 경우에는 어떻게 해야 할까요? 여기에서 투영을 사용합니다.
중첩된 필드를 다양한 방식으로 투영할 수 있습니다. 여기에서는 중첩 필드를 투영하기 위한 다음 솔루션에 대해 알아봅니다.
$project
집계 단계 사용$unset
집계 단계 사용forEach()
루프 사용mapReduce()
함수 사용
위의 접근 방식을 배우기 위해 하나의 문서를 포함하는 nested
라는 컬렉션을 만들어 보겠습니다. 아래에 제공된 쿼리를 사용하여 후속 조치를 취할 수도 있습니다.
예제 코드:
// MongoDB version 5.0.8
> db.nested.insertOne(
{
"name": {
"first_name": "Mehvish",
"last_name": "Ashiq",
},
"contact": {
"phone":{"type": "manager", "number": "123456"},
"email":{ "type": "office", "mail": "delfstack@example.com"}
},
"country_name" : "Australien",
"posting_locations" : [
{
"city_id" : 19398,
"city_name" : "Bondi Beach (Sydney)"
},
{
"city_id" : 31101,
"city_name" : "Rushcutters Bay (Sydney)"
},
{
"city_id" : 31022,
"city_name" : "Wolly Creek (Sydney)"
}
],
"regions" : {
"region_id" : 796,
"region_name" : "Australien: New South Wales (Sydney)"
}
}
);
db.nested.find().pretty();
사용 삽입된 데이터를 보려면 mongo 셸에서
$project
집계 단계를 사용하여 MongoDB에서 중첩 필드 프로젝트
예제 코드:
// MongoDB version 5.0.8
> var current_location = "posting_locations";
> var project = {};
> project["id"] = "$"+current_location+".city_id";
> project["name"] = "$"+current_location+".city_name";
> project["regions"] = 1;
> var find = {};
> find[current_location] = {"$exists":true};
> db.nested.aggregate([
{ $match : find },
{ $project : project }
]).pretty()
출력:
{
"_id" : ObjectId("62a96d397c7e3688aea26d0d"),
"regions" : {
"region_id" : 796,
"region_name" : "Australien: New South Wales (Sydney)"
},
"id" : [
19398,
31101,
31022
],
"name" : [
"Bondi Beach (Sydney)",
"Rushcutters Bay (Sydney)",
"Wolly Creek (Sydney)"
]
}
여기에서 current_location
이라는 변수에 posting_locations
라는 첫 번째 수준 필드를 저장합니다.
그런 다음 해당 변수를 사용하여 city_id
및 city_name
에 액세스하고 project
개체에 대괄호 표기법을 사용하여 project
개체에 대한 속성을 만드는 동안 project
개체에 저장합니다. 또한 project["regions"]
에 regions
필드를 저장합니다.
다음으로 aggregate()
메서드에서 문서를 일치시키는 데 사용할 find
라는 다른 객체가 있습니다. aggregate()
메소드에서 $match
단계를 사용하여 문서를 일치시키고 $project
단계를 사용하여 중첩이든 첫 번째 수준이든 필드를 투영합니다.
$project
를 사용하여 출력에 표시할 필드를 지정합니다. 필터 쿼리 없이 지정된 중첩 필드만 투영하는 데 관심이 있는 경우 다음 솔루션을 사용할 수 있습니다.
예제 코드:
// MongoDB version 5.0.8
> var current_location = "posting_locations";
> db.nested.aggregate({
$project: {
"_id": 0,
"city_id": "$" + current_location + ".city_id",
"city_name": "$" + current_location + ".city_name",
"regions": 1
}
}).pretty();
출력:
{
"regions" : {
"region_id" : 796,
"region_name" : "Australien: New South Wales (Sydney)"
},
"city_id" : [
19398,
31101,
31022
],
"city_name" : [
"Bondi Beach (Sydney)",
"Rushcutters Bay (Sydney)",
"Wolly Creek (Sydney)"
]
}
$unset
집계 단계를 사용하여 MongoDB에서 지정된 필드를 제외한 중첩 필드 가져오기
예제 코드:
// MongoDB version 5.0.8
> db.nested.aggregate({
$unset: ["posting_locations.city_id", "contact", "regions", "name", "_id"]
}).pretty()
출력:
{
"country_name" : "Australien",
"posting_locations" : [
{
"city_name" : "Bondi Beach (Sydney)"
},
{
"city_name": "Rushcutters Bay (Sydney)"
},
{
"city_name": "Wolly Creek (Sydney)"
}
]
}
여기에서 지정된 필드 또는 필드 배열을 삭제하는 데 사용되는 $unset
연산자를 사용합니다.
포함된 문서 또는 문서 배열을 지정하기 위해 점 표기법을 사용한다는 것을 기억하십시오. $unset
연산자는 지정된 필드가 없으면 작업을 수행하지 않습니다.
$
를 사용하여 배열의 요소를 일치시킬 때 $unset
연산자는 일치하는 요소를 배열에서 제거하는 대신 null
로 대체합니다. 이 동작은 요소 위치와 배열 크기를 일관되게 유지하는 데 도움이 됩니다.
forEach()
루프를 사용하여 MongoDB에서 중첩 필드 가져오기
예제 코드:
// MongoDB version 5.0.8
> var bulk = db.newcollection.initializeUnorderedBulkOp(),
counter = 0;
> db.nested.find().forEach(function(doc) {
var document = {};
document["name"] = doc.name.first_name + " " + doc.name.last_name;
document["phone"] = doc.contact.phone.number;
document["mail"] = doc.contact.email.mail;
bulk.insert(document);
counter++;
if (counter % 1000 == 0) {
bulk.execute();
bulk = db.newcollection.initializeUnorderedBulkOp();
}
});
> if (counter % 1000 != 0) { bulk.execute(); }
다음과 유사한 내용이 표시됩니다.
BulkWriteResult({
"writeErrors" : [ ],
"writeConcernErrors" : [ ],
"nInserted" : 1,
"nUpserted" : 0,
"nMatched" : 0,
"nModified" : 0,
"nRemoved" : 0,
"upserted" : [ ]
})
그런 다음 mongo 셸에서 아래 명령을 실행하여 투영된 필드를 확인합니다.
// MongoDB version 5.0.8
> db.newcollection.find().pretty();
출력:
{
"_id" : ObjectId("62a96f2d7c7e3688aea26d0e"),
"name" : "Mehvish Ashiq",
"phone" : "123456",
"mail" : "delfstack@example.com"
}
이 예제 코드를 배우기 위해 특정 중첩 필드를 가져와 새 컬렉션에 삽입한다고 가정합니다. 여기에서 변환된 필드를 새 컬렉션에 문서로 삽입하면 중첩된
컬렉션의 크기에 따라 작업에 영향을 줄 수 있습니다.
새로운 정렬되지 않은 대량 삽입
API를 사용하여 느린 삽입 성능을 피할 수 있습니다. 대량으로 전송하여 삽입 작업을 간소화하고 작업의 성공 여부에 대한 피드백을 실시간으로 제공합니다.
따라서 bulk insert
API를 사용하여 newcollection
컬렉션에 원하는 데이터 구조를 삽입합니다. 여기서 nested
컬렉션 커서의 forEach()
루프를 사용하여 완전히 새로운 문서가 생성됩니다. 새 속성을 생성하기 위해 대괄호 표기법을 사용합니다.
이 코드에서는 많은 양의 데이터가 있다고 가정합니다. 따라서 대량 삽입 작업을 수행하기 위해 1000
배치의 서버로 작업을 보냅니다.
결과적으로 각 요청을 보내는 것이 아니라 서버에 1000번의 요청마다 한 번씩만 보내기 때문에 좋은 성능을 제공합니다.
mapReduce()
메서드를 사용하여 MongoDB에서 중첩 필드 투영
예제 코드:
// MongoDB version 5.0.8
> function map() {
for(var i in this.posting_locations) {
emit({
"country_id" : this.country_id,
"city_id" : this.posting_locations[i].city_id,
"region_id" : this.regions.region_id
},1);
}
}
> function reduce(id,docs) {
return Array.sum(docs);
}
> db.nested.mapReduce(map,reduce,{ out : "map_reduce_output" } )
이제 다음 쿼리를 실행하여 출력을 확인합니다.
// MongoDB version 5.0.8
> db.map_reduce_output.find().pretty();
출력:
{
"_id" : {
"country_id" : undefined,
"city_id" : 19398,
"region_id" : 796
},
"value" : 1
}
{
"_id" : {
"country_id" : undefined,
"city_id" : 31022,
"region_id" : 796
},
"value" : 1
}
{
"_id" : {
"country_id" : undefined,
"city_id" : 31101,
"region_id" : 796
},
"value" : 1
}
이 예제 코드에서는 mapReduce()
함수를 사용하여 nested
컬렉션의 모든 문서에 대해 맵 축소를 수행합니다. 이를 위해 아래에 간략하게 설명된 3단계 프로세스를 따라야 합니다.
-
모든 입력 문서를 처리하기 위해
map()
함수를 정의하십시오. 이 함수에서this
키워드는 map-reduce 작업에 의해 처리 중인 현재 문서를 참조하고emit()
함수는 지정된 값을 키에 매핑하고 반환합니다. -
여기에서 데이터 집계가 발생하는 실제 장소인 해당
reduce()
함수를 정의합니다. 두 개의 인수(keys
및values
)가 필요합니다. 우리의 코드 예제는id
와docs
를 사용합니다.docs
의 요소는map()
메소드의emit()
함수에 의해 반환됩니다. 이 단계에서reduce()
함수는docs
배열을 해당 값(요소)의 합으로 줄입니다. -
마지막으로
map()
및reduce()
함수를 사용하여nested
컬렉션의 모든 문서에 대해 맵 축소를 수행합니다.out
을 사용하여 이 경우map_reduce_output
인 지정된 컬렉션에 출력을 저장합니다.