MongoDB 프로젝트 중첩 필드

Mehvish Ashiq 2023년1월30일
  1. MongoDB 프로젝트 중첩 필드
  2. $project 집계 단계를 사용하여 MongoDB에서 중첩 필드 프로젝트
  3. $unset 집계 단계를 사용하여 MongoDB에서 지정된 필드를 제외한 중첩 필드 가져오기
  4. forEach() 루프를 사용하여 MongoDB에서 중첩 필드 가져오기
  5. mapReduce() 메서드를 사용하여 MongoDB에서 중첩 필드 투영
MongoDB 프로젝트 중첩 필드

오늘은 $project$unset 집계 단계, forEach() 루프 및 mapReduce() 메서드를 사용하여 MongoDB에서 데이터를 쿼리하는 동안 중첩 필드를 투영하는 방법을 배웁니다.

MongoDB 프로젝트 중첩 필드

MongoDB에서는 find() 메소드를 사용하여 모든 문서를 검색할 수 있지만 특정 중첩 필드에만 액세스하려는 경우에는 어떻게 해야 할까요? 여기에서 투영을 사용합니다.

중첩된 필드를 다양한 방식으로 투영할 수 있습니다. 여기에서는 중첩 필드를 투영하기 위한 다음 솔루션에 대해 알아봅니다.

  1. $project 집계 단계 사용
  2. $unset 집계 단계 사용
  3. forEach() 루프 사용
  4. 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_idcity_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() 함수를 정의합니다. 두 개의 인수(keysvalues)가 필요합니다. 우리의 코드 예제는 iddocs를 사용합니다.

    docs의 요소는 map() 메소드의 emit() 함수에 의해 반환됩니다. 이 단계에서 reduce() 함수는 docs 배열을 해당 값(요소)의 합으로 줄입니다.

  • 마지막으로 map()reduce() 함수를 사용하여 nested 컬렉션의 모든 문서에 대해 맵 축소를 수행합니다. out을 사용하여 이 경우 map_reduce_output인 지정된 컬렉션에 출력을 저장합니다.
Mehvish Ashiq avatar Mehvish Ashiq avatar

Mehvish Ashiq is a former Java Programmer and a Data Science enthusiast who leverages her expertise to help others to learn and grow by creating interesting, useful, and reader-friendly content in Computer Programming, Data Science, and Technology.

LinkedIn GitHub Facebook

관련 문장 - MongoDB Projection