$sort (집계)
정의
호환성
다음 환경에서 호스팅되는 배포에 $sort
사용할 수 있습니다.
MongoDB Atlas: 클라우드에서의 MongoDB 배포를 위한 완전 관리형 서비스
MongoDB Enterprise: MongoDB의 구독 기반 자체 관리 버전
MongoDB Community: MongoDB의 소스 사용 가능 무료 자체 관리 버전
구문
$sort
단계의 프로토타입 형식은 다음과 같습니다.
{ $sort: { <field1>: <sort order>, <field2>: <sort order> ... } }
$sort
(은)는 정렬 기준이 되는 필드와 해당 정렬 순서를 지정하는 문서를 사용합니다. <sort order>
(은)는 다음 값 중 하나를 가집니다.
값 | 설명 |
---|---|
| 오름차순으로 정렬합니다. |
| 내림차순으로 정렬합니다. |
|
|
여러 필드에서 정렬하는 경우 정렬 순서는 왼쪽에서 오른쪽으로 평가됩니다. 예를 들어 위 형식에서 문서는 먼저 <field1>
기준으로 정렬됩니다. 그런 다음 동일한 <field1>
값을 가진 문서가 <field2>
를 기준으로 더 정렬됩니다.
행동
성능
$sort
데이터를 처리하기 전에 파이프라인이 블로킹 단계에서 모든 입력 데이터가 조회될 때까지 대기하도록 하는 블로킹 단계입니다. 블로킹 단계는 여러 단계가 있는 파이프라인에 대한 병렬 처리를 줄이기 때문에 성능을 저하시킬 수 있습니다. 블로킹 단계는 대규모 데이터 세트에 대해 상당한 양의 메모리를 사용할 수도 있습니다.
제한
최대 32개의 키를 기준으로 정렬할 수 있습니다.
중복 필드가 포함된 정렬 패턴을 제공하면 오류가 발생합니다.
정렬 일관성
MongoDB는 특정 순서에 따라 문서를 컬렉션에 저장하지 않습니다. 중복 값이 포함된 필드를 정렬할 때 해당 값이 포함된 문서는 임의의 순서로 반환될 수 있습니다.
일관적인 정렬 순서가 필요한 경우 고유값이 포함된 필드를 정렬에 하나 이상 포함하세요. 이를 보장하는 가장 쉬운 방법은 정렬 쿼리에 _id
필드를 포함하는 것입니다.
다음의 restaurant
컬렉션을 고려해 보세요.
db.restaurants.insertMany( [ { "_id" : 1, "name" : "Central Park Cafe", "borough" : "Manhattan"}, { "_id" : 2, "name" : "Rock A Feller Bar and Grill", "borough" : "Queens"}, { "_id" : 3, "name" : "Empire State Pub", "borough" : "Brooklyn"}, { "_id" : 4, "name" : "Stan's Pizzaria", "borough" : "Manhattan"}, { "_id" : 5, "name" : "Jane's Deli", "borough" : "Brooklyn"}, ] )
다음 명령은 $sort
단계를 사용해 borough
필드를 정렬합니다.
db.restaurants.aggregate( [ { $sort : { borough : 1 } } ] )
이 예시에서는 borough
필드에 Manhattan
및 Brooklyn
에 대한 중복 값이 모두 포함되어 정렬 순서가 일치하지 않을 수 있습니다. 문서는 borough
의 알파벳순로 반환되지만 borough
의 중복 값을 포함하는 문서의 순서는 동일한 정렬을 여러 번 실행할 때 동일하지 않을 수 있습니다. 예를 들어 위 명령을 두 번 실행한 결과는 다음과 같습니다.
{ "_id" : 3, "name" : "Empire State Pub", "borough" : "Brooklyn" } { "_id" : 5, "name" : "Jane's Deli", "borough" : "Brooklyn" } { "_id" : 1, "name" : "Central Park Cafe", "borough" : "Manhattan" } { "_id" : 4, "name" : "Stan's Pizzaria", "borough" : "Manhattan" } { "_id" : 2, "name" : "Rock A Feller Bar and Grill", "borough" : "Queens" } { "_id" : 5, "name" : "Jane's Deli", "borough" : "Brooklyn" } { "_id" : 3, "name" : "Empire State Pub", "borough" : "Brooklyn" } { "_id" : 4, "name" : "Stan's Pizzaria", "borough" : "Manhattan" } { "_id" : 1, "name" : "Central Park Cafe", "borough" : "Manhattan" } { "_id" : 2, "name" : "Rock A Feller Bar and Grill", "borough" : "Queens" }
borough
값은 여전히 알파벳순으로 정렬되지만 borough
(즉, Manhattan
및 Brooklyn
)의 중복 값을 포함하는 문서의 순서는 동일하지 않습니다.
일관적인 정렬을 하려면 고유 값만 포함하는 필드를 이 정렬에 추가하세요. 다음 명령은 $sort
단계를 사용하여 borough
필드와 _id
필드를 모두 정렬합니다.
db.restaurants.aggregate( [ { $sort : { borough : 1, _id: 1 } } ] )
_id
필드는 항상 고유한 값만 포함하도록 보장되므로 반환된 정렬 순서는 동일한 정렬을 여러 번 실행해도 항상 동일합니다.
배열 필드로 정렬
MongoDB가 배열 값 필드에 따라 문서를 정렬할 때 정렬 키는 정렬이 오름차순인지 내림차순인지에 따라 달라집니다.
오름차순 정렬에서는 정렬 키는 배열에서 가장 낮은 값입니다.
내림차순 정렬에서 정렬 키는 배열에서 가장 높은 값입니다.
쿼리 필터는 정렬 키 선택에 영향을 미치지 않습니다.
예를 들어 다음 문서를 사용하여 shoes
컬렉션을 생성합니다.
db.shoes.insertMany( [ { _id: 'A', sizes: [ 7, 11 ] }, { _id: 'B', sizes: [ 8, 9, 10 ] } ] )
다음 쿼리는 sizes
필드를 기준으로 문서를 오름차순 및 내림차순으로 정렬합니다.
// Ascending sort db.shoes.aggregate( [ { $sort: { sizes: 1 } } ] ) // Descending sort db.shoes.aggregate( [ { $sort: { sizes: -1 } } ] )
앞선 두 쿼리는 모두 _id: 'A'
인 문서를 먼저 반환합니다. 이는 sizes
배열 항목에서 크기 7
과 11
이 각각 가장 낮고 가장 높기 때문입니다.
예시
오름차순/내림차순 정렬
정렬 기준이 되는 필드에 대해 다음 예시에서와 같이 정렬 순서를 1
또는 -1
로 설정하여 각각 오름차순 또는 내림차순 정렬을 지정합니다.
db.users.aggregate( [ { $sort : { age : -1, posts: 1 } } ] )
이 작업은 users
collection에 있는 문서를 age
필드에 따라 내림차순으로 정렬한 다음 posts
필드의 값에 따라 오름차순으로 정렬합니다.
정렬 작업에서 서로 다른 BSON types 의 값을 비교할 때 MongoDB는 가장 낮은 것부터 가장 높은 것까지 다음과 같은 비교 순서를 사용합니다:
MinKey(내부 유형)
Null
숫자(정수, long, double, decimals)
기호, 문자열
객체
배열
BinData
ObjectId
부울
날짜
타임스탬프
정규 표현식
JavaScript 코드
MaxKey(내부 유형)
특정 유형에 대한 비교/정렬 순서에 대한 자세한 내용은 비교/정렬 순서를 참조하세요.
텍스트 점수 메타데이터 정렬
참고
$text
이 페이지에서는 자체 관리형(Atlas에서 관리하지 않는) 배포를 위한 일반 텍스트 쿼리 기능을 제공합니다. MongoDB Atlas에서 호스팅되는 데이터의 경우 MongoDB는 향상된 전체 텍스트 쿼리 솔루션인 Atlas Search를 제공합니다.
$text
를 포함하는 파이프라인의 경우 { $meta: "textScore"
}
표현식을 사용하여 관련성 점수를 내림차순으로 정렬할 수 있습니다. { <sort-key> }
문서에서 { $meta: "textScore" }
표현식을 임의의 필드 이름으로 설정합니다. 필드 이름은 쿼리 시스템에서 무시됩니다. 예시:
db.users.aggregate( [ { $match: { $text: { $search: "operating" } } }, { $sort: { score: { $meta: "textScore" }, posts: -1 } } ] )
이 작업은 $text
연산자를 사용하여 문서를 일치시킨 다음 "textScore"
메타데이터를 기준으로 내림차순으로 정렬하고 posts
필드를 기준으로 내림차순으로 정렬합니다. 정렬 문서의 score
필드 이름은 쿼리 시스템에서 무시됩니다. 이 파이프라인에서 "textScore"
메타데이터는 프로젝션에 포함되지 않으며 일치하는 문서의 일부로 반환되지 않습니다. 자세한 내용은 $meta
를 참조하세요.
$sort
연산자 및 메모리
$sort
+ $limit
메모리 최적화
$sort
가 $limit
앞에 오고 문서 수를 수정하는 중간 단계가 없을 경우, 옵티마이저는 $limit
를 $sort
에 병합할 수 있습니다. 이렇게 하면 $sort
연산을 진행하는 과정에서 상위 n
개의 결과만 유지할 수 있고(여기서 n
은 지정된 제한값 의미), MongoDB는 메모리에 n
개의 항목만 저장하면 됩니다. 이 최적화는 allowDiskUse
가 true
이고 n
항목이 집계 메모리 제한을 초과하는 경우에도 여전히 적용됩니다.
최적화는 릴리스 간에 변경될 수 있습니다.
$sort
및 메모리 제한
$sort
단계는 인메모리 정렬의 경우 100 메가바이트의 RAM으로 제한됩니다. 기본적으로 단계가 이 제한을 초과하면 $sort
에서 오류가 발생합니다. 파이프라인 처리가 더 많은 공간을 차지하도록 하려면 allowDiskUse 옵션을 사용하여 집계 파이프라인 단계에서 임시 파일에 데이터를 쓸 수 있도록 설정합니다.
$sort
연산자 및 성능
$sort
연산자는 파이프라인의 첫 번째 단계에서 사용되거나 $match
단계 앞에만 있는 경우 인덱스를 활용할 수 있습니다.
샤딩된 클러스터에서 $sort
를 사용하면 각 샤드는 가능한 경우 인덱스를 사용해 결과 문서를 정렬합니다. 그런 다음 mongos
또는 샤드 중 하나가 스트리밍 병합 정렬을 수행합니다.