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

MongoDB에서 하위 문서 일치 기준으로 정렬하는 방법

MongoDB에서 하위 문서(sub-document) 일치 조건을 기준으로 데이터를 정렬하려면 애그리게이션 프레임워크(aggregate)를 활용하는 것이 가장 효과적입니다. 일반적인 find() 메서드만으로는 배열 내부의 특정 요소 값을 기준으로 정렬하기 어렵기 때문입니다. 이번 글에서는 실제 예제를 통해 그 과정을 단계별로 살펴보겠습니다.

샘플 컬렉션 생성하기

먼저 학생 이름(StudentName)과 나이(Age), 점수(StudentScore)를 담은 하위 문서 배열(StudentDetails)로 구성된 컬렉션을 생성하고 문서 두 개를 삽입합니다.

> db.sortBySubDocumentsDemo.insertOne(
   {
      "StudentName": "Chris",
      "StudentDetails": [
         {
            "Age":21,
            "StudentScore":91
         },
         {
            "Age":22,
            "StudentScore":99
         },
         {
            "Age":21,
            "StudentScore":93
         }
      ]
   }
);
{
   "acknowledged" : true,
   "insertedId" : ObjectId("5cd57e297924bb85b3f48942")
}
> db.sortBySubDocumentsDemo.insertOne(
   {
      "StudentName": "Robert",
      "StudentDetails": [
         {
            "Age":24,
            "StudentScore":78
         },
         {
            "Age":21,
            "StudentScore":86
         },
         {
            "Age":23,
            "StudentScore":45
         }
      ]
   }
);
{
   "acknowledged" : true,
   "insertedId" : ObjectId("5cd57e4c7924bb85b3f48943")
}

저장된 문서 조회하기

find() 메서드를 사용하면 컬렉션에 저장된 모든 문서를 확인할 수 있습니다.

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

위 쿼리를 실행하면 다음과 같은 결과가 출력됩니다.

{
   "_id" : ObjectId("5cd57e297924bb85b3f48942"),
   "StudentName" : "Chris",
   "StudentDetails" : [
      {
         "Age" : 21,
         "StudentScore" : 91
      },
      {
         "Age" : 22,
         "StudentScore" : 99
      },
      {
         "Age" : 21,
         "StudentScore" : 93
      }
   ]
}
{
   "_id" : ObjectId("5cd57e4c7924bb85b3f48943"),
   "StudentName" : "Robert",
   "StudentDetails" : [
      {
         "Age" : 24,
         "StudentScore" : 78
      },
      {
         "Age" : 21,
         "StudentScore" : 86
      },
      {
         "Age" : 23,
         "StudentScore" : 45
      }
   ]
}

하위 문서 일치 기준으로 정렬하는 쿼리

다음은 StudentDetails 배열에서 Age가 21인 하위 문서만 필터링한 후, StudentScore 값을 기준으로 오름차순 정렬하는 애그리게이션 쿼리입니다.

> db.sortBySubDocumentsDemo.aggregate([
   {$match: { 'StudentDetails.Age': 21 }},
   {$unwind: '$StudentDetails'},
   {$match: {'StudentDetails.Age': 21}},
   {$project: {_id: 0, "StudentName": 1, 'StudentDetails.StudentScore': 1}},
   {$sort: { 'StudentDetails.StudentScore': 1 }},
   {$limit: 5}
]);

애그리게이션 파이프라인 단계별 설명

  • $match: Age가 21인 하위 문서를 포함한 문서만 우선 필터링합니다.
  • $unwind: StudentDetails 배열을 개별 하위 문서 단위로 분해합니다.
  • $match (재적용): 배열이 분해된 후 다시 한번 Age가 21인 요소만 남깁니다.
  • $project: StudentName과 StudentDetails.StudentScore 필드만 선택하여 출력하고 _id는 제외합니다.
  • $sort: StudentScore를 기준으로 오름차순(1) 정렬합니다.
  • $limit: 최대 5개의 결과만 반환하도록 제한합니다.

쿼리를 실행하면 다음과 같은 결과가 출력됩니다.

{ "StudentName" : "Robert", "StudentDetails" : { "StudentScore" : 86 } }
{ "StudentName" : "Chris", "StudentDetails" : { "StudentScore" : 91 } }
{ "StudentName" : "Chris", "StudentDetails" : { "StudentScore" : 93 } }

출력 결과를 보면 흥미로운 점을 확인할 수 있습니다. Chris의 점수(91, 93)가 Robert의 점수(86)보다 높지만, 정렬은 문서 전체가 아닌 개별 하위 문서 단위로 수행되기 때문에 Robert의 86점이 가장 먼저 나타납니다. 또한 Age가 21인 하위 문서는 전체 6개 중 3개뿐이므로 $limit을 5로 설정했더라도 실제로는 3개의 결과만 반환됩니다.