인덱스에는 정렬된 기록이 포함되므로 MongoDB는 정렬 필드를 포함하는 인덱스에서 정렬 결과를 얻을 수 있습니다. 정렬이 쿼리 조건자와 동일한 인덱스를 사용하는 경우 MongoDB는 정렬 작업을 지원하기 위해 여러 인덱스를 사용할 수 있습니다.
MongoDB 인덱스 또는 인덱스를 사용하여 정렬 순서를 가져올 수 없는 경우 MongoDB 데이터에 대해 메모리 내 정렬 작업을 수행해야 합니다.
MongoDB 6.0부터, 서버가 파이프라인 실행 단계에 100 메가바이트 이상의 메모리가 필요할 경우, 그 쿼리가 { allowDiskUse: false }를 지정하지 않는 한 MongoDB는 자동으로 임시 파일을 디스크에 씁니다.
인덱스 사용하는 정렬 작업은 인메모리 정렬보다 성능이 더 좋은 경우가 많습니다.
참고
단일 필드 인덱스로 정렬
단일 필드에 오름차순 또는 내림차순 인덱스가 있는 경우 정렬 필드 작업은 어느 방향으로든 이루어질 수 있습니다.
예를 들어, records 컬렉션의 a 필드에 오름차순 인덱스를 생성합니다.
db.records.createIndex( { a: 1 } )
이 인덱스는 다음에서 a의 오름차순 정렬을 지원할 수 있습니다.
db.records.find().sort( { a: 1 } )
인덱스를 역순으로 탐색하여 에서 다음과 같이 a에 대한 내림차순 정렬을 지원할 수도 있습니다.
db.records.find().sort( { a: -1 } )
여러 필드에서 정렬
복합 인덱스를 생성하여 여러 필드에서 정렬을 지원합니다.
인덱스의 모든 키 또는 서브세트에 대해 정렬을 지정할 수 있지만, 정렬 키는 인덱스에 표시되는 것과 동일한 순서 로 나열되어야 합니다. 예를 들어, 인덱스 키 패턴 { a: 1, b: 1
}은 { a: 1, b: 1 }의 정렬을 지원할 수 있지만 { b: 1, a:
1 }의 정렬은 지원할 수 없습니다.
쿼리가 정렬에 복합 인덱스를 사용하려면 cursor.sort() 문서의 모든 키에 지정된 정렬 방향이 인덱스 키 패턴 또는 그 역과 일치해야 합니다. 예를 들어 인덱스 키 패턴 { a: 1, b: -1 }은 { a: 1, b: -1 } 및 { a: -1, b: 1 }의 정렬을 지원할 수 있지만 { a: -1, b: -1 } 또는 {a: 1, b: 1}의 정렬은 지원하지 않습니다.
정렬 및 인덱스 접두사
정렬 키가 인덱스 키 또는 인덱스 접두사에 해당하는 경우, MongoDB는 인덱스를 사용하여 쿼리 결과를 정렬할 수 있습니다. 복합 인덱스의 접두사는 인덱스 키 패턴의 시작 부분에 있는 하나 이상의 키로 구성된 하위 집합입니다.
예를 들어 data 컬렉션에 복합 인덱스를 생성합니다.
db.data.createIndex( { a:1, b: 1, c: 1, d: 1 } )
그러면 아래와 같은 항목이 인덱스의 접두사에 해당합니다.
{ a: 1 } { a: 1, b: 1 } { a: 1, b: 1, c: 1 }
다음 쿼리 및 정렬 작업은 인덱스 접두사를 사용하여 결과를 정렬합니다. 이러한 작업은 메모리에 있는 결과 세트를 정렬할 필요가 없습니다.
예시 | Index Prefix |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
인덱스의 접두사 키가 쿼리 술어와 정렬 모두에 나타나는 다음 예시를 살펴보세요.
db.data.find( { a: { $gt: 4 } } ).sort( { a: 1, b: 1 } )
이러한 경우 MongoDB는 인덱스를 사용하여 정렬에서 지정한 순서대로 문서를 조회할 수 있습니다. 예시에서 볼 수 있듯이 쿼리 술어의 인덱스 접두사는 정렬의 접두사와 다를 수 있습니다.
인덱스의 정렬 및 접두사가 없는 하위 집합
인덱스는 접두사가 아닌 인덱스 키 패턴 하위 집합의 정렬 작업을 지원할 수 있습니다. 이렇게 하려면 정렬 키 앞에 오는 모든 접두사 키에 대한 동등성 조건이 쿼리에 포함되어야 합니다.
예를 들어 data 컬렉션의 인덱스는 다음과 같습니다.
{ a: 1, b: 1, c: 1, d: 1 }
다음 작업에서는 인덱스를 사용하여 정렬 순서를 확보할 수 있습니다.
예시 | Index Prefix |
|---|---|
|
|
|
|
|
|
마지막 작업에서 볼 수 있듯이 쿼리 문서에서 정렬 하위 집합 앞에 있는 인덱스 필드에만 동등성 조건이 적용되어야 합니다. 다른 인덱스 필드는 다른 조건을 지정할 수 있습니다.
쿼리가 정렬 사양 앞에 오거나 겹치는 인덱스 접두사에 동등성 조건을 지정하지 않으면 작업에서 인덱스를 효율적으로 사용할 수 없습니다. 예를 들어 다음 작업은 { c: 1 }의 정렬 문서를 지정하지만 쿼리 문서는 선행 인덱스 필드 a 및 b의 동등성 매치를 포함하지 않습니다.
db.data.find( { a: { $gt: 2 } } ).sort( { c: 1 } ) db.data.find( { c: 5 } ).sort( { c: 1 } )
이러한 작업은 { a: 1, b: 1,
c: 1, d: 1 } 인덱스를 효율적으로 사용할 수 없으며 문서를 조회하는 데 인덱스를 사용하지 않을 수도 있습니다.
인덱스 정렬 순서
인덱스된 문서 모음은 키 필드에 여러 데이터 유형을 가질 수 있습니다. 인덱스에 여러 데이터 유형을 가진 키가 있는 경우 인덱스는 BSON 유형 정렬 순서에 따라 정렬됩니다.
인덱스 정렬 예시를 참조하세요.
인덱스 사용 및 데이터 정렬
문자열 비교에 인덱스를 사용하려면 작업에서 동일한 데이터 정렬도 지정해야 합니다. 즉, 작업에서 다른 데이터 정렬을 지정하는 경우 데이터 정렬이 있는 인덱스는 인덱싱된 필드에서 문자열 비교를 수행하는 작업을 지원할 수 없습니다.
경고
데이터 정렬이 없는 인덱스의 경우 데이터 정렬 인식 인덱스 키가 인덱스 키보다 클 수 있는데, 데이터 정렬로 구성된 인덱스는 정렬 순서를 달성하기 위해 ICU 데이터 정렬 키를 사용하기 때문입니다.
예시
다음 예시는 인덱스 키의 유형이 동일하거나 다른 경우의 정렬을 보여줍니다.
keyTypes 컬렉션을 생성합니다.
db.keyTypes.insertMany( [ { seqNum: 1, seqType: null, type: "null" }, { seqNum: 29, seqType: null, type: "null" }, { seqNum: 2, seqType: Int32("10"), type: "Int32" }, { seqNum: 28, seqType: Int32("10"), type: "Int32" }, { seqNum: 3, seqType: Long("10"), type: "Long" }, { seqNum: 27, seqType: Long("10"), type: "Long" }, { seqNum: 4, seqType: Decimal128("10"), type: "Decimal128" }, { seqNum: 26, seqType: Decimal128("10"), type: "Decimal128" }, { seqNum: 5, seqType: Double("10"), type: "Double" }, { seqNum: 25, seqType: Double("10"), type: "Double" }, { seqNum: 6, seqType: String("10"), type: "String" }, { seqNum: 24, seqType: String("10"), type: "String" }, { seqNum: 7, seqType: [ "1", "2", "3" ], type: "Array" }, { seqNum: 23, seqType: [ "1", "2", "3" ], type: "Array" }, { seqNum: 8, seqType: [ [1], [2], [3] ], type: "Array" }, { seqNum: 22, seqType: [ [1], [2], [3] ], type: "Array " }, { seqNum: 9, seqType: [ 1, 2, 3 ], type: "Array" }, { seqNum: 21, seqType: [ 1, 2, 3 ], type: "Array" }, { seqNum: 10, seqType: true, type: "Boolean" }, { seqNum: 11, seqType: new Timestamp(), type: "Timestamp" }, { seqNum: 12, seqType: new Date(), type: "Date" }, { seqNum: 13, seqType: new ObjectId(), type: "ObjectId" }, ] )
시퀀스 번호(seqNum) 및 유형(seqType) 필드에 인덱스를 생성합니다.
db.keyTypes.createIndex( { seqNum: 1 } ) db.keyTypes.createIndex( { seqType: 1 } )
find()를 사용하여 컬렉션을 쿼리합니다. 프로젝션 문서{ _id: 0 }는 출력 디스플레이에서 _id 필드를 표시하지 않습니다.
db.keyTypes.find( {}, { _id: 0 } )
문서가 삽입된 순서대로 반환됩니다.
{ seqNum: 1, seqType: null, type: 'null' }, { seqNum: 29, seqType: null, type: 'null' }, { seqNum: 2, seqType: 10, type: 'Int32' }, { seqNum: 28, seqType: 10, type: 'Int32' }, { seqNum: 3, seqType: Long("10"), type: 'Long' }, { seqNum: 27, seqType: Long("10"), type: 'Long' }, { seqNum: 4, seqType: Decimal128("10"), type: 'Decimal128' }, // Output truncated
시퀀스 번호(seqNum) 인덱스는 동일한 유형의 값을 가집니다. seqNum 인덱스를 사용하여 keyTypes 컬렉션을 쿼리합니다.
db.keyTypes.find( {}, { _id: 0 } ).sort( { seqNum: 1} )
seqNum 키는 정수입니다. 문서는 번호 순서대로 반환됩니다.
{ seqNum: 1, seqType: null, type: 'null' }, { seqNum: 2, seqType: 10, type: 'Int32' }, { seqNum: 3, seqType: Long("10"), type: 'Long' }, { seqNum: 4, seqType: Decimal128("10"), type: 'Decimal128' }, { seqNum: 5, seqType: 10, type: 'Double' }, { seqNum: 6, seqType: '10', type: 'String' }, { seqNum: 7, seqType: [ '1', '2', '3' ], type: 'Array' }, // Output truncated
시퀀스 유형(seqType) 인덱스는 다른 유형의 값을 가집니다. seqType 인덱스를 사용하여 keyTypes 컬렉션을 쿼리합니다.
db.keyTypes.find( {}, { _id: 0 } ).sort( { seqType: 1} )
문서는 BSON 유형 정렬 순서로 반환됩니다.
{ seqNum: 1, seqType: null, type: 'null' }, { seqNum: 29, seqType: null, type: 'null' }, { seqNum: 9, seqType: [ 1, 2, 3 ], type: 'Array' }, { seqNum: 21, seqType: [ 1, 2, 3 ], type: 'Array' }, { seqNum: 2, seqType: 10, type: 'Int32' }, { seqNum: 28, seqType: 10, type: 'Int32' }, { seqNum: 3, seqType: Long("10"), type: 'Long' }, { seqNum: 27, seqType: Long("10"), type: 'Long' }, { seqNum: 4, seqType: Decimal128("10"), type: 'Decimal128' }, { seqNum: 26, seqType: Decimal128("10"), type: 'Decimal128' }, { seqNum: 5, seqType: 10, type: 'Double' }, { seqNum: 25, seqType: 10, type: 'Double' }, { seqNum: 7, seqType: [ '1', '2', '3' ], type: 'Array' }, { seqNum: 23, seqType: [ '1', '2', '3' ], type: 'Array' }, { seqNum: 6, seqType: '10', type: 'String' }, { seqNum: 24, seqType: '10', type: 'String' }, { seqNum: 8, seqType: [ [ 1 ], [ 2 ], [ 3 ] ], type: 'Array' }, { seqNum: 22, seqType: [ [ 1 ], [ 2 ], [ 3 ] ], type: 'Array ' }, { seqNum: 13, seqType: ObjectId("6239e3922604d5a7478df071"), type: 'ObjectId' }, { seqNum: 10, seqType: true, type: 'Boolean' }, { seqNum: 12, seqType: ISODate("2022-03-22T14:56:18.100Z"), type: 'Date' }, { seqNum: 11, seqType: Timestamp({ t: 1647960978, i: 1 }), type: 'Timestamp' }
숫자 형식(Int32, Long, Decimal128, Double)은 다른 유형과 비교해 동일합니다.
숫자 BSON 유형에서 숫자 유형을 정렬합니다.
Int32
Long
Decimal128
Double