와일드카드 인덱스는 내장된 객체 및 배열 필드를 인덱싱할 때 특정 동작이 있습니다.
필드가 객체인 경우 와일드카드 인덱스는 객체로 내려가 그 내용을 인덱싱합니다. 와일드카드 인덱스는 발견되는 추가로 내장된 문서로 계속 내려갑니다.
필드 가 배열 인 경우 와일드카드 인덱스 는 배열 을 순회하고 각 요소를 인덱싱합니다.
요소가 객체 인 경우 와일드카드 인덱스 는 객체 로 내려가 해당 내용을 인덱스 합니다.
요소가 배열 (즉, 상위 배열 내에 직접 포함된 배열)인 경우 와일드카드 인덱스 는 포함된 배열 을 순회하지 않고 전체 배열 을 단일 값으로 인덱싱합니다.
다른 모든 필드의 경우 인덱스는 기본 값을 저장합니다. 기본 값은 객체나 배열이 아닌 값입니다.
와일드카드 인덱스 는 기본 값에 도달할 때까지 추가 포함된 객체 또는 배열을 계속 순회합니다. 그런 다음 해당 필드 의 전체 경로와 함께 기본 값을 인덱싱합니다.
포함된 객체의 와일드카드 인덱스
와일드카드 인덱스 는 내장된 객체 를 발견하면 객체 로 내려가 해당 내용을 인덱싱합니다. 예를 예시 다음 문서 를 가정해 보겠습니다.
db.users.insertOne( { account: { username: "SuperAdmin01", contact: { phone: "123-456-7890", email: "xyz@example.com" }, access: { group: "admin" } } } )
account
필드를 포함하는 와일드카드 인덱스는 account
객체로 내려가 해당 내용을 탐색하고 인덱싱합니다.
자체가 객체인 각 하위 필드(예:
account.contact
및account.access
)의 경우 인덱스는 객체로 내려가 해당 내용을 기록합니다.다른 모든 하위 필드의 경우 인덱스 인덱스 기록합니다.
샘플 문서가 주어지면 와일드카드 인덱스는 다음 기록을 인덱스에 추가합니다.
"account.username" : "SuperAdmin01"
"account.contact.phone" : "123-456-7890"
"account.contact.email" : "xyz@example.com"
"account.access.group" : "admin"
배열의 와일드카드 인덱스
와일드카드 인덱스 는 배열 배열 탐색하여 요소를 인덱스 합니다. 배열 요소 자체가 배열 (포함된 배열)인 경우 인덱스 는 내용을 탐색하는 대신 전체 포함된 배열 을 값으로 기록합니다.
예를 예시 다음 문서 를 가정해 보겠습니다.
db.fleet.insertOne( { "ship": { "coordinates" : [ [-5, 10], [-7, 8] ], "type": "Cargo Ship", "captains": [ { "name": "Francis Drake", "crew": [ "first mate", "carpenter" ] } ] } } )
ship
필드 를 포함하는 와일드카드 인덱스 는 객체 로 내려가 해당 콘텐츠를 탐색하고 인덱스 합니다.
배열 인 각 요소에 대해 다음을 수행합니다.
요소 자체가 배열 인 경우(예: 내장된 배열) 인덱스 는 전체 배열 을 값으로 기록합니다.
요소가 객체 인 경우 인덱스 는 객체 로 내려가 해당 내용을 순회하고 인덱스 합니다.
요소가 기본 값인 경우 인덱스 는 해당 값을 기록합니다.
배열과 객체가 아닌 필드의 경우 인덱스 는 원시 값을 인덱스 에 기록합니다.
샘플 문서가 주어지면 와일드카드 인덱스는 다음 기록을 인덱스에 추가합니다.
"ship.coordinates" : [-5, 10]
"ship.coordinates" : [-7, 8]
"ship.type" : "Cargo Ship"
"ship.captains.name" : "Francis Drake"
"ship.captains.crew" : "first mate"
"ship.captains.crew" : "carpenter"
명시적 배열 인덱스가 있는 쿼리
와일드카드 인덱스는 인덱싱 중에 배열 에 있는 지정된 요소의 배열 위치를 기록 하지 않습니다. 그러나 MongoDB 는 하나 이상의 명시적 배열 인덱스가 있는 필드 경로 를 포함하는 쿼리 를 수행하기 위해 와일드카드 인덱스 를 사용할 수 있습니다.
예를 예시 다음 문서 를 가정해 보겠습니다.
db.fleet.insertOne( { "ship": { "coordinates" : [ [-5, 10], [-7, 8] ], "type": "Cargo Ship", "captains": [ { "name": "Francis Drake", "crew": [ "first mate", "carpenter" ] } ] } } )
ship
필드 를 포함하는 와일드카드 인덱스 를 생성합니다.
db.fleet.createIndex( { "ship.$**": 1 } )
ship.coordinates
및 ship.captains
의 인덱스 레코드에는 각 요소의 배열 위치가 포함되어 있지 않습니다. 와일드카드 인덱스는 요소를 인덱스 에 기록할 때 배열 요소 위치를 무시합니다. 그러나 와일드카드 인덱스는 명시적 배열 인덱스를 포함하는 쿼리를 계속 지원 수 있습니다.
MongoDB 는 와일드카드 인덱스 를 사용하여 이 쿼리 를 수행할 수 있습니다.
db.fleet.find( { "ship.captains.0.name": "Francis Drake" } )
쿼리 는 샘플 문서 를 반환합니다.
[ { _id: ObjectId("6350537db1fac2ee2e957efc"), ship: { coordinates: [ [ -5, 10 ], [ -7, 8 ] ], type: 'Cargo Ship', captains: [ { name: 'Francis Drake', crew: [ 'first mate', 'carpenter' ] } ] } } ]
MongoDB는 이 쿼리를 수행하기 위해 와일드카드 인덱스를 사용할 수 없습니다.
db.fleet.find( { "ship.coordinates.0.1": 10 } )
ship.coordinates
필드 에 내장된 배열이 포함되어 있습니다. 와일드카드 인덱스는 포함된 배열의 개별 값을 기록 하지 않습니다. 대신 전체 내장된 배열 을 기록 합니다. 결과적으로 와일드카드 인덱스 는 포함된 배열 값에서 일치하는 항목을 지원 수 없으며, MongoDB 는 컬렉션 스캔 을 사용하여 쿼리 를 수행합니다.
배열 인덱스 제한
MongoDB 는 경로에 8 이하의 명시적 배열 인덱스가 포함된 경우에만 와일드카드 인덱스 를 사용하여 쿼리 의 지정된 필드 경로 를 충족할 수 있습니다. 필드 경로 에 8 개 이상의 명시적 인덱스가 포함된 경우 쿼리 를 수행하기 위해 MongoDB 는 다음 중 하나를 수행합니다.
다른 적합한 인덱스 를 선택합니다.
컬렉션 스캔 을 수행합니다.
와일드카드 인덱스 자체는 문서를 인덱싱 하는 동안 문서 를 탐색하는 깊이에 제한이 없습니다. 이 제한은 정확한 배열 인덱스를 명시적으로 지정하는 쿼리에만 적용됩니다.