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

MongoDB 중첩 문서에서 키만 추출해 표시하는 방법

MongoDB에서 배열 안에 여러 개의 하위 문서가 포함된 중첩(nested) 구조를 다루다 보면, 각 문서에 실제로 어떤 필드(키)가 존재하는지 값 없이 키 이름만 확인하고 싶은 경우가 있습니다. 이번 글에서는 애그리게이션 파이프라인의 $reduce, $map, $objectToArray 연산자를 조합하여 중첩 문서의 키 목록만 깔끔하게 추출하는 방법을 알아보겠습니다.

1. 샘플 컬렉션 생성하기

먼저 데모용 컬렉션을 만들고 문서를 하나 삽입합니다. details 필드는 두 개의 하위 문서를 담고 있는 배열이며, 두 번째 문서에는 isMarried라는 추가 키가 있다는 점에 주목하세요.

> db.demo740.insertOne({
...    "details":
...    [
...       {
...          Name:"Chris",
...          Age:21,
...          CountryName:"US"
...       },
...       {
...          Name:"Bob",
...          Age:20,
...          CountryName:"UK",
...          isMarried:true
...       }
...    ]
... });
{
   "acknowledged" : true,
   "insertedId" : ObjectId("5ead700c57bb72a10bcf066d")
}

2. 저장된 문서 확인하기

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

> db.demo740.find();

위 명령을 실행하면 다음과 같은 결과가 출력됩니다.

"_id" : ObjectId("5ead700c57bb72a10bcf066d"), "details" : [ { "Name" : "Chris", "Age" : 21, "CountryName" : "US" }, { "Name" : "Bob", "Age" : 20, "CountryName" : "UK", "isMarried" : true } ] }

3. 중첩 문서의 키만 추출하는 쿼리

다음은 애그리게이션 파이프라인을 사용해 details 배열 내 모든 하위 문서의 키를 하나의 배열로 모아 반환하는 쿼리입니다.

> db.demo740.aggregate([
...    {
...       $project: {
...          ListKeys: {
...             $reduce: {
...                input: "$details",
...                initialValue: [],
...                in: {
...                   $concatArrays: [
...                      "$$value",
...                      {
...                         $map: {
...                            input: {
...                               $objectToArray: "$$this"
...                            },
...                            in: "$$this.k"
...                         }
...                      }
...                   ]
...                }
...             }
...          }
...       }
...    }
... ]).pretty()

쿼리 동작 원리

  • $objectToArray: 각 하위 문서를 {k: 키, v: 값} 형태의 요소로 이루어진 배열로 변환합니다.
  • $map: 변환된 배열에서 k(키 이름)만 뽑아 새로운 배열을 만듭니다.
  • $reduce + $concatArrays: 배열의 각 요소를 순회하면서 추출된 키 배열들을 하나의 배열로 누적 병합합니다.

4. 실행 결과

쿼리를 실행하면 다음과 같이 중첩 문서에 포함된 모든 키가 하나의 배열로 출력됩니다.

{
   "_id" : ObjectId("5ead700c57bb72a10bcf066d"),
   "ListKeys" : [
      "Name",
      "Age",
      "CountryName",
      "Name",
      "Age",
      "CountryName",
      "isMarried"
   ]
}

결과를 보면 첫 번째 하위 문서의 키(Name, Age, CountryName)와 두 번째 하위 문서의 키(Name, Age, CountryName, isMarried)가 모두 포함되어 있습니다. 만약 중복 없이 고유한 키 목록만 필요하다면, 이 결과 뒤에 $unwind$group 단계를 추가하거나 클라이언트 측에서 중복을 제거하면 됩니다.