Computer >> 컴퓨터 >  >> 프로그래밍 >> MongoDB

MongoDB에서 특정 중첩 속성(nested properties) 프로젝션하기

MongoDB에서 특정 중첩 속성에 대해 프로젝션(projection)을 수행하려면 aggregate() 메서드를 사용해야 합니다. 일반적인 find()의 프로젝션으로는 깊은 중첩 구조 내부의 특정 키만 선택적으로 필터링하기 어렵기 때문인데, 이때 집계 파이프라인의 $objectToArray, $filter, $arrayToObject 연산자를 조합하면 원하는 결과를 얻을 수 있습니다.

1. 샘플 컬렉션 생성

먼저 중첩된 문서를 포함하는 컬렉션을 생성해 보겠습니다.

> db.demo379.insertOne(
...    {
...       "details1" : {
...          "details2" : {
...             "details3" : {
...                "10" : "John",
...                "50" : "Chris",
...                "40" : "David",
...                "30":"Mike"
...             }
...          }
...       }
...    }
... );
{
   "acknowledged" : true,
   "insertedId" : ObjectId("5e5a94f82ae06a1609a00b10")
}

2. 전체 문서 확인

find() 메서드를 사용해 컬렉션의 모든 문서를 조회합니다.

> db.demo379.find().pretty();

위 쿼리는 다음과 같은 출력을 생성합니다.

{
   "_id" : ObjectId("5e5a94f82ae06a1609a00b10"),
   "details1" : {
      "details2" : {
         "details3" : {
            "10" : "John",
            "30" : "Mike",
            "40" : "David",
            "50" : "Chris"
         }
      }
   }
}

3. 특정 중첩 속성에 대한 프로젝션 쿼리

이제 특정 조건(여기서는 키 값이 35 이상 60 이하)에 맞는 중첩 속성만 추출하는 프로젝션 쿼리를 작성해 보겠습니다.

> db.demo379.aggregate([
...    { "$addFields": {
...       "details1.details2.details3": {
...          "$arrayToObject": {
...             "$filter": {
...                "input": { "$objectToArray": "$details1.details2.details3" },
...                "as": "out",
...                "cond": {
...                   "$and": [
...                      { "$gte": ["$$out.k", "35"] },
...                      { "$lte": ["$$out.k", "60"] },
...                   ]
...                }
...             }
...          }
...       }
...    } }
... ])

쿼리 동작 방식

  • $objectToArray: details3 객체를 키(key)-값(value) 쌍의 배열로 변환합니다.
  • $filter: 변환된 배열에서 조건($gte, $lte)을 만족하는 요소만 걸러냅니다.
  • $arrayToObject: 필터링된 배열을 다시 객체 형태로 되돌립니다.
  • $addFields: 기존 필드를 새로 계산된 값으로 대체합니다.

위 쿼리는 다음과 같은 출력을 생성합니다.

{ "_id" : ObjectId("5e5a94f82ae06a1609a00b10"), "details1" : { "details2" : { "details3" : { "40" : "David", "50" : "Chris" } } } }

출력 결과를 보면 키가 35~60 범위에 해당하는 "40": "David""50": "Chris"만 남고, 나머지 항목들은 제거된 것을 확인할 수 있습니다.