Multikey Indexes
배열 값이 포함된 필드를 인덱싱하기 위해 MongoDB는 배열의 각 고유 요소에 대한 인덱스 키를 만듭니다. 이러한 멀티키 인덱스는 배열 필드에 대한 효율적인 쿼리를 지원합니다. 두 스칼라 값 [1] 을 모두 포함하는 배열에 대해 다중 키 인덱스를 구성할 수 있습니다(예: 문자열, 숫자) 및 중첩 문서가 포함됩니다. 배열에 동일한 값의 인스턴스가 여러 개 포함된 경우 인덱스에는 해당 값에 대한 항목이 하나만 포함됩니다.
[1] | 스칼라 값은 내장된 문서도 배열도 아닌 값을 나타냅니다. |
호환성
MongoDB Atlas 에서 호스팅되는 배포에 멀티키 인덱스를 사용할 수 있습니다.
MongoDB Atlas에서 호스팅되는 배포의 인덱스 관리에 대해 자세히 알아보려면 인덱스 생성, 보기, 삭제 및 숨기기를 참조하세요.
멀티키 인덱스 생성
멀티키 인덱스 를 만들려면 db.collection.createIndex()
메서드를 사용합니다.
db.coll.createIndex( { <field>: < 1 or -1 > } )
인덱싱된 필드가 배열인 경우 MongoDB는 멀티키 인덱스를 자동으로 생성합니다. 즉, 멀티키 유형을 명시적으로 지정할 필요가 없습니다.
참고
WiredTiger 및 인메모리 스토리지 엔진에만 해당됩니다.
멀티키 인덱스의 경우, MongoDB는 어떤 인덱싱된 필드가 인덱스를 멀티키 인덱스로 만드는지를 추적합니다. 이 정보를 추적하면 MongoDB 쿼리 엔진이 더 엄격한 인덱스 경계를 사용할 수 있습니다.
인덱스 바운드
인덱스가 멀티키인 경우 인덱스 바운드 계산은 특별한 규칙을 따릅니다. 멀티키 인덱스 바운드에 대한 자세한 내용은 멀티키 인덱스 바운드를 참조 하세요.
고유한 멀티키 인덱스
고유 인덱스 의 경우, 고유 제약 조건은 단일 문서가 아닌 collection의 개별 문서에 적용됩니다.
고유 제약 조건은 개별 문서에 적용되므로 고유 한 멀티키 인덱스 의 경우 해당 문서의 인덱스 키 값이 다른 문서의 인덱스 키 값과 중복되지 않는 한 문서에 배열 요소가 있을 수 있으며, 이 경우 인덱스 키 값이 반복될 수 있습니다.
자세한 내용은 개별 문서 간 고유 제약 조건을 참조하세요.
제한 사항
복합 멀티키 인덱스
복합 멀티키 인덱스의 경우, 각 인덱스된 문서에는 값이 배열인 인덱스된 필드가 최대 하나만 있을 수 있습니다. 즉:
문서에서 둘 이상의 인덱싱할 필드가 배열인 경우 복합 멀티키 인덱스를 생성할 수 없습니다. 예를 들어, 다음 문서가 포함된 collection을 생각해 보겠습니다.
{ _id: 1, a: [ 1, 2 ], b: [ 1, 2 ], category: "AB - both arrays" } a
및b
필드가 모두 배열이므로 collection에 복합 멀티키 인덱스{ a: 1, b: 1 }
를 생성할 수 없습니다.또는 복합 멀티키 인덱스가 이미 존재하는 경우 이 제한을 위반하는 문서를 삽입할 수 없습니다.
다음 문서가 포함된 collection을 가정해 보겠습니다.
{ _id: 1, a: [1, 2], b: 1, category: "A array" } { _id: 2, a: 1, b: [1, 2], category: "B array" } 복합 멀티키 인덱스
{ a: 1, b: 1 }
은 허용되는데, 이는 각 문서에 대해 복합 멀티키 인덱스로 인덱싱되는 필드가 배열 하나뿐이기 때문입니다. 즉,a
및b
필드 모두에 대한 배열 값이 포함된 문서가 없습니다.그러나 복합 멀티키 인덱스를 생성한 후
a
및b
필드가 모두 배열인 문서를 삽입하려고 하면 MongoDB가 삽입에 실패합니다.
필드가 문서 배열인 경우 포함된 필드를 인덱스화하여 복합 인덱스를 생성할 수 있습니다. 예를 들어, 다음 문서가 포함된 collection을 생각해 보겠습니다.
{ _id: 1, a: [ { x: 5, z: [ 1, 2 ] }, { z: [ 1, 2 ] } ] } { _id: 2, a: [ { x: 5 }, { z: 4 } ] }
{ "a.x": 1, "a.z": 1 }
에 복합 인덱스를 만들 수 있습니다. 최대 하나의 인덱싱된 필드가 배열이 될 수 있는 제한도 적용됩니다.
정렬
MongoDB 4.4 의 배열 필드에 대한 정렬 동작이 변경된 결과로, 멀티키 인덱스 로 인덱싱된 배열을 정렬할 때 다음과 같은 경우를 제외하고 쿼리 계획에는 블로킹 정렬 단계가 포함됩니다.
모든 정렬 필드의 인덱스 경계 는
[MinKey, MaxKey]
이며 ,멀티키 인덱스 필드의 경계에는 정렬 패턴과 동일한 경로 접두사가 없습니다.
샤드 키
멀티키 인덱스를 샤드 키 인덱스로 지정할 수 없습니다 .
그러나 샤드 키 인덱스가 복합 인덱스의 접두사 인 경우, 다른 키 중 하나가 (즉, 샤드 키의 일부가 아닌 키)는 배열을 인덱싱합니다. 복합 멀티키 인덱스는 성능에 영향을 미칠 수 있습니다.
해시 인덱스
해시된 인덱스는 멀티키일 수 없습니다 .
지원되는 쿼리
멀티키 인덱스는 다음 조건이 충족되는 경우 쿼리를 처리할 수 있습니다.
쿼리가 배열 필드를 반환하지 않습니다(즉, 배열이 쿼리 프로젝션에 포함되지 않습니다). 즉, 쿼리를 처리하려면 다중 키 인덱스가 복합이어야 합니다.
$elemMatch
를 포함하지 않습니다.다른 모든 지원되는 쿼리 요구 사항을 충족합니다.
예를 들어 이러한 문서가 포함된matches
컬렉션을 생각해 보겠습니다:
db.matches.insertMany( [ { name: "Joe", event: [ "open", "tournament" ] }, { name: "Bill", event: [ "match", "championship" ] } ] )
matches
컬렉션은 event
및 name
필드에 복합 다중 키 인덱스를 가지고 있습니다:
db.matches.createIndex( { event: 1, name: 1 } )
event
필드에 배열 값이 포함되어 있으므로 이전 인덱스는 멀티키입니다.
인덱스는 다음과 같은 쿼리를 다룹니다.
db.matches.find( { event: 'championship' }, { _id: 0, name: 1 } ) db.matches.find( { name: 'Bill', event: 'championship' }, { _id: 0, name: 1 } )
프로젝션에 event
배열 필드가 포함되어 있기 때문에 다음 쿼리는 인덱스에 포함되지 않습니다.
db.matches.find( { event: 'championship' }, { _id: 0, event: 1 } )
배열 필드 전체에 대한 쿼리
쿼리 필터 가 배열 전체에 대해 정확히 일치하는 항목을 지정하면 MongoDB는 멀티키 인덱스를 사용하여 쿼리 배열의 첫 번째 요소를 조회할 수 있지만 멀티키 인덱스 스캔을 사용하여 전체 배열을 찾을 수는 없습니다. 대신, 멀티키 인덱스를 사용하여 쿼리 배열의 첫 번째 요소를 조회한 후 MongoDB는 관련 문서를 검색하고 배열이 쿼리의 배열과 일치하는 문서를 필터링합니다.
예를 들어, 다음 문서가 포함된 inventory
collection을 생각해 보겠습니다.
{ _id: 5, type: "food", item: "aaa", ratings: [ 5, 8, 9 ] } { _id: 6, type: "food", item: "bbb", ratings: [ 5, 9 ] } { _id: 7, type: "food", item: "ccc", ratings: [ 9, 5, 8 ] } { _id: 8, type: "food", item: "ddd", ratings: [ 9, 5 ] } { _id: 9, type: "food", item: "eee", ratings: [ 5, 9, 5 ] }
collection에 ratings
필드에 대한 멀티키 인덱스가 있습니다.
db.inventory.createIndex( { ratings: 1 } )
다음 쿼리는 ratings
필드가 [ 5, 9 ]
배열인 문서를 찾습니다.
db.inventory.find( { ratings: [ 5, 9 ] } )
MongoDB는 멀티키 인덱스를 사용하여 ratings
배열의 임의 위치에 5
가 있는 문서를 찾을 수 있습니다. 그런 다음 MongoDB는 이러한 문서를 조회하고 ratings
배열이 쿼리 배열 [ 5, 9 ]
와 동일한 문서를 필터링합니다.
$expr
$expr
멀티키 인덱스를 지원하지 않습니다.
예시
기본 배열 인덱스
다음 문서를 사용하여 survey
컬렉션을 만듭니다.
db.survey.insertOne( { _id: 1, item: "ABC", ratings: [ 2, 5, 9 ] } )
필드 ratings
에 인덱스를 만듭니다.
db.survey.createIndex( { ratings: 1 } )
ratings
필드에 배열이 포함되어 있으므로 ratings
의 인덱스는 멀티키입니다. 멀티키 인덱스에는 각각 동일한 문서를 가리키는 다음 세 개의 인덱스 키가 포함되어 있습니다.
2
,5
및9
.
내장된 문서가 있는 배열 인덱스
중첩된 객체를 포함하는 배열 필드에 멀티키 인덱스를 생성할 수 있습니다.
다음 형식의 문서가 포함된 inventory
컬렉션을 가정해 보겠습니다.
{ _id: 1, item: "abc", stock: [ { size: "S", color: "red", quantity: 25 }, { size: "S", color: "blue", quantity: 10 }, { size: "M", color: "blue", quantity: 50 } ] } { _id: 2, item: "def", stock: [ { size: "S", color: "blue", quantity: 20 }, { size: "M", color: "blue", quantity: 5 }, { size: "M", color: "black", quantity: 10 }, { size: "L", color: "red", quantity: 2 } ] } { _id: 3, item: "ijk", stock: [ { size: "M", color: "blue", quantity: 15 }, { size: "L", color: "blue", quantity: 100 }, { size: "L", color: "red", quantity: 25 } ] } ...
다음 작업은 stock.size
및 stock.quantity
필드에 멀티키 인덱스를 생성합니다.
db.inventory.createIndex( { "stock.size": 1, "stock.quantity": 1 } )
복합 멀티키 인덱스는 다음 예시에서와 같이 인덱싱된 필드를 모두 포함하는 조건자와 인덱스 접두사 "stock.size"
만 포함하는 조건자가 모두 포함된 쿼리를 지원할 수 있습니다.
db.inventory.find( { "stock.size": "M" } ) db.inventory.find( { "stock.size": "S", "stock.quantity": { $gt: 20 } } )
MongoDB가 멀티키 인덱스 바운드를 결합하는 방법에 대한 자세한 내용은 멀티 키 인덱스 바운드를 참조하세요. 복합 인덱스 및 접두사의 동작에 대한 자세한 내용은 복합 인덱스 및 접두사를 참조하세요 .
복합 멀티키 인덱스는 다음 예제와 같은 정렬 작업도 지원할 수 있습니다.
db.inventory.find( ).sort( { "stock.size": 1, "stock.quantity": 1 } ) db.inventory.find( { "stock.size": "M" } ).sort( { "stock.quantity": 1 } )
복합 인덱스의 동작 및 정렬 작업에 대한 자세한 내용은 인덱스를 사용하여 쿼리 결과 정렬을 참조하세요.