MongoDB에서 하위 문서 기준으로 정렬하기
MongoDB에서 배열 형태로 저장된 하위 문서(subdocument)를 특정 필드 값 기준으로 정렬하려면, 일반적인 find().sort()만으로는 해결할 수 없습니다. 이 경우 애그리게이션 파이프라인의 $unwind, $sort, $group 단계를 조합해야 합니다. 아래 예제를 통해 전체 과정을 단계별로 살펴보겠습니다.
1단계: 예제 컬렉션 생성
insertOne() 메서드를 사용해 마감일(DueDate)과 값(Value)을 담은 details 배열을 가진 문서 두 개를 demo245 컬렉션에 삽입합니다.
> db.demo245.insertOne(
... {
... "_id": 101,
... "details": [
... { "DueDate": new ISODate("2019-01-10"), "Value": 45 },
... { "DueDate": new ISODate("2019-11-10"), "Value": 34 }
... ]
... }
...);
{ "acknowledged" : true, "insertedId" : 101 }
> db.demo245.insertOne(
... {
... "_id": 102,
... "details": [
... { "DueDate": new ISODate("2019-12-11"), "Value": 29 },
... { "DueDate": new ISODate("2019-03-10"), "Value": 78 }
... ]
... }
...);
{ "acknowledged" : true, "insertedId" : 102 }
2단계: 저장된 문서 조회
find() 메서드를 사용하면 컬렉션의 모든 문서를 확인할 수 있습니다.
> db.demo245.find();
실행 결과는 다음과 같습니다.
{
"_id" : 101, "details" : [
{ "DueDate" : ISODate("2019-01-10T00:00:00Z"), "Value" : 45 },
{ "DueDate" : ISODate("2019-11-10T00:00:00Z"), "Value" : 34 }
]
}
{
"_id" : 102, "details" : [
{ "DueDate" : ISODate("2019-12-11T00:00:00Z"), "Value" : 29 },
{ "DueDate" : ISODate("2019-03-10T00:00:00Z"), "Value" : 78 }
]
}
3단계: 하위 문서 정렬 쿼리 실행
details 배열 안의 Value 필드를 기준으로 내림차순 정렬하려면 다음과 같이 애그리게이션 파이프라인을 구성합니다.
- $unwind – details 배열을 요소 하나하나로 분해합니다.
- $sort – _id는 오름차순(1), details.Value는 내림차순(-1)으로 정렬합니다.
- $group – _id를 기준으로 문서를 다시 묶고, 정렬된 순서대로 details 배열을 재구성($push)합니다.
> db.demo245.aggregate([
... { "$unwind": "$details" },
... { "$sort": { "_id": 1, "details.Value": -1 } },
... { "$group": {
... "_id": "$_id",
... "details": { "$push": "$details" }
... }},
... { "$sort": { "details.Value": -1 } }
...])
실행 결과, 각 문서의 details 배열이 Value 값이 큰 순서부터 정렬되어 출력됩니다.
{ "_id" : 101, "details" : [ { "DueDate" : ISODate("2019-01-10T00:00:00Z"), "Value" : 45 }, { "DueDate" : ISODate("2019-11-10T00:00:00Z"), "Value" : 34 } ] }
{ "_id" : 102, "details" : [ { "DueDate" : ISODate("2019-03-10T00:00:00Z"), "Value" : 78 }, { "DueDate" : ISODate("2019-12-11T00:00:00Z"), "Value" : 29 } ] }
오름차순으로 정렬하고 싶다면 위 쿼리에서 -1을 1로 변경하면 됩니다. 이처럼 $unwind로 배열을 풀어낸 뒤 정렬하고 다시 그룹화하는 패턴을 사용하면, MongoDB에서도 하위 문서를 원하는 기준대로 자유롭게 정렬할 수 있습니다.