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

MongoDB에서 내장 문서 배열을 상위 레벨로 이동하고 집계 파이프라인으로 키/값 변환하기

MongoDB 집계 파이프라인에서 $replaceRoot 단계를 사용하면 배열 형태로 저장된 내장 문서(임베디드 도큐먼트)의 필드들을 상위 레벨로 끌어올리고, 동시에 키/값 구조를 원하는 형태로 변환할 수 있습니다.

$replaceRoot는 입력 문서 전체를 지정한 새 문서로 대체하는 역할을 합니다. 이때 _id 필드를 포함한 기존의 모든 필드가 새 문서의 내용으로 교체되므로, 기존 필드를 유지하고 싶다면 반드시 새 루트 문서에 명시적으로 포함시켜야 합니다.

샘플 데이터 생성하기

먼저 데모용 컬렉션을 만들고 문서를 삽입해 보겠습니다.

> db.demo733.insertOne(
...    {
...       "SubjectDetails":
...       [
...           {
...               SubjectName:"MongoDB",
...               "Marks":85
...           },
...           {
...               SubjectName:"MySQL",
...               "Marks":90
...           },
...           {
...               SubjectName:"PL/SQL",
...               "Marks":98
...           }
...       ]
...    }
... );
{
    "acknowledged" : true,
    "insertedId" : ObjectId("5eac6e6156e85a39df5f6342")
}

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

> db.demo733.find();

위 쿼리는 다음과 같은 결과를 출력합니다.

{ "_id" : ObjectId("5eac6e6156e85a39df5f6342"), "SubjectDetails" : [ { "SubjectName" : "MongoDB", "Marks" : 85 }, { "SubjectName" : "MySQL", "Marks" : 90 }, { "SubjectName" : "PL/SQL", "Marks" : 98 } ] }

내장 문서 배열을 상위 레벨로 이동하는 쿼리

아래는 집계 파이프라인을 활용해 SubjectDetails 배열 안의 내장 문서들을 상위 레벨로 이동하고, 과목명을 키로, 점수를 값으로 갖도록 변환하는 쿼리입니다.

핵심 로직은 다음과 같습니다.

  • $map: 배열의 각 요소를 [키, 값] 쌍으로 변환합니다.
  • $arrayToObject: 키/값 쌍의 배열을 하나의 객체로 변환합니다.
  • $mergeObjects: 기존 _id와 변환된 객체를 하나의 문서로 병합합니다.
  • $replaceRoot: 병합된 최종 문서를 새 루트로 지정합니다.
> db.demo733.aggregate([
...    {
...       $replaceRoot: {
...          newRoot: {
...             $mergeObjects: [
...                { _id: "$_id" },
...                { $arrayToObject: { $map: { input: "$SubjectDetails", in: [ "$$this.SubjectName", "$$this.Marks" ] } } }
...             ]
...          }
...       }
...    }
... ]).pretty()

실행 결과는 다음과 같습니다. 각 과목 이름이 최상위 키가 되고, 점수가 해당 값으로 매핑된 것을 확인할 수 있습니다.

{
    "_id" : ObjectId("5eac6e6156e85a39df5f6342"),
    "MongoDB" : 85,
    "MySQL" : 90,
    "PL/SQL" : 98
}