문서 메뉴
문서 홈
/
MongoDB 매뉴얼
/

와일드카드 인덱스

이 페이지의 내용

  • 와일드카드 인덱스 만들기
  • 고려 사항
  • 행동
  • 제한 사항
  • 와일드카드 인덱스 쿼리/정렬 지원

MongoDB는 쿼리를 지원하기 위해 필드 또는 필드 세트에 인덱스를 생성하는 것을 지원합니다. MongoDB는 동적 스키마를 지원하므로 애플리케이션은 이름을 미리 알 수 없거나 임의적인 필드를 쿼리할 수 있습니다.

MongoDB 버전 4.2의 새로운 기능

MongoDB 4.2에는 알 수 없거나 임의의 필드에 대한 쿼리를 지원하기 위한 와일드카드 인덱스가 도입되었습니다.

userMetadata 필드 아래에서 사용자 정의 데이터를 캡처하고 해당 데이터에 대한 쿼리를 지원하는 애플리케이션을 생각해 보세요.

{ "userMetadata" : { "likes" : [ "dogs", "cats" ] } }
{ "userMetadata" : { "dislikes" : "pickles" } }
{ "userMetadata" : { "age" : 45 } }
{ "userMetadata" : "inactive" }

관리자는 userMetadata 의 모든 하위 필드에 대한 쿼리를 지원하는 인덱스를 만들고자 합니다.

userMetadata 에 대한 와일드카드 인덱스는 userMetadata, userMetadata.likes, userMetadata.dislikesuserMetadata.age 에 대한 단일 필드 쿼리를 지원할 수 있습니다.

db.userData.createIndex( { "userMetadata.$**" : 1 } )

인덱스는 다음 쿼리를 지원할 수 있습니다.

db.userData.find({ "userMetadata.likes" : "dogs" })
db.userData.find({ "userMetadata.dislikes" : "pickles" })
db.userData.find({ "userMetadata.age" : { $gt : 30 } })
db.userData.find({ "userMetadata" : "inactive" })

userMetadata 에 대한 와일드카드가 아닌 인덱스는 userMetadata 값에 대한 쿼리만 지원할 수 있습니다.

중요

와일드카드 인덱스는 워크로드 기반 인덱스 계획을 대체하도록 설계되지 않았습니다. 쿼리를 지원하는 인덱스를 만드는 방법에 대한 자세한 내용은 쿼리를 지원하는인덱스 만들기 를 참조하세요. 와일드카드 인덱스 제한에 대한 전체 문서는 와일드카드 인덱스 제한을 참조하세요 .

중요

와일드카드 인덱스를 생성하려면 mongod featureCompatibilityVersion4.2 여야 합니다. fCV 설정에 대한 지침은 MongoDB 5.0 배포에서 기능 호환성 버전 설정을 참조하세요.

createIndexes 데이터베이스 명령 또는 해당 shell 헬퍼인 createIndex() 또는 createIndexes() 을 사용하여 와일드카드 인덱스를 생성할 수 있습니다.

특정 필드의 값을 인덱싱하려면 다음을 수행합니다.

db.collection.createIndex( { "fieldA.$**" : 1 } )

이 와일드카드 인덱스를 사용하면 MongoDB는 fieldA 의 모든 값을 인덱싱합니다. 필드가 중첩된 문서 또는 배열인 경우 와일드카드 인덱스는 문서/배열에 재귀되어 문서/배열의 모든 필드에 대한 값을 저장합니다.

예를 들어 product_catalog 컬렉션의 문서에 product_attributes 필드가 포함될 수 있습니다. product_attributes 필드에는 내장된 문서 및 배열을 포함하여 임의의 중첩 필드가 포함될 수 있습니다.

{
"product_name" : "Spy Coat",
"product_attributes" : {
"material" : [ "Tweed", "Wool", "Leather" ]
"size" : {
"length" : 72,
"units" : "inches"
}
}
}
{
"product_name" : "Spy Pen",
"product_attributes" : {
"colors" : [ "Blue", "Black" ],
"secret_feature" : {
"name" : "laser",
"power" : "1000",
"units" : "watts",
}
}
}

다음 작업은 product_attributes 필드에 와일드카드 인덱스를 생성합니다.

db.products_catalog.createIndex( { "product_attributes.$**" : 1 } )

와일드카드 인덱스는 product_attributes 또는 포함된 필드에 대한 임의의 단일 필드 쿼리를 지원할 수 있습니다.

db.products_catalog.find( { "product_attributes.size.length" : { $gt : 60 } } )
db.products_catalog.find( { "product_attributes.material" : "Leather" } )
db.products_catalog.find( { "product_attributes.secret_feature.name" : "laser" } )

참고

경로별 와일드카드 인덱스 구문은 wildcardProjection 옵션과 호환되지 않습니다. 자세한 내용은 wildcard 인덱스에 대한 옵션을 참조하세요.

예제 는 단일 필드 경로에 와일드카드 인덱스 생성을 참조하세요.

문서의 모든 필드 값( _id 제외)을 인덱스하려면 "$**" 을(를) 인덱스 키로 지정합니다.

db.collection.createIndex( { "$**" : 1 } )

MongoDB는 이 와일드카드 인덱스를 사용하여 collection의 각 문서에 대한 모든 필드를 인덱싱합니다. 지정된 필드가 중첩된 문서 또는 배열인 경우 와일드카드 인덱스는 문서/배열에 재귀되어 문서/배열의 모든 필드에 대한 값을 저장합니다.

예제 는 모든 필드 경로에 와일드카드 인덱스 생성하기 항목을 참조하세요.

참고

와일드카드 인덱스는 기본적으로 _id 필드를 생략합니다. 와일드카드 인덱스에 _id 필드를 포함하려면 해당 필드를 wildcardProjection 문서에 명시적으로 포함해야 합니다. 자세한 내용 wildcard 인덱스 옵션을 참조하세요.

문서에서 여러 특정 필드의 값을 인덱싱하려면 다음을 수행합니다.

db.collection.createIndex(
{ "$**" : 1 },
{ "wildcardProjection" :
{ "fieldA" : 1, "fieldB.fieldC" : 1 }
}
)

MongoDB는 이 와일드카드 인덱스를 사용하여 collection의 각 문서에 지정된 필드에 대한 모든 값을 인덱싱합니다. 지정된 필드가 중첩된 문서 또는 배열인 경우 와일드카드 인덱스는 문서/배열에 재귀되어 문서/배열의 모든 필드에 대한 값을 저장합니다.

참고

와일드카드 인덱스는 _id 필드를 명시적으로 포함하는 경우를 제외하고 wildcardProjection 문서에서 포함 및 제외 문을 혼합하는 것을 지원하지 않습니다. wildcardProjection 에 대한 자세한 내용 은 wildcard 인덱스 옵션 을 참조 하세요 .

예시 는 와일드카드 인덱스 커버리지에 특정 필드 포함을 참조하세요.

특정 필드 경로를 제외한 문서 내 모든 필드의 필드를 인덱싱하려면 다음을 수행합니다.

db.collection.createIndex(
{ "$**" : 1 },
{ "wildcardProjection" :
{ "fieldA" : 0, "fieldB.fieldC" : 0 }
}
)

MongoDB는 이 와일드카드 인덱스를 사용하여 지정된 필드 경로를 제외한 컬렉션의 각 문서에 대한 모든 필드를 인덱싱합니다. 지정된 필드가 중첩된 문서 또는 배열인 경우 와일드카드 인덱스는 문서/배열에 재귀되어 문서/배열의 모든 필드에 대한 값을 저장합니다.

예시 는 와일드카드 인덱스 커버리지에서 특정 필드 생략을 참조하세요.

참고

와일드카드 인덱스는 _id 필드를 명시적으로 포함하는 경우를 제외하고 wildcardProjection 문서에서 포함 및 제외 문을 혼합하는 것을 지원하지 않습니다. wildcardProjection 에 대한 자세한 내용 은 wildcard 인덱스 옵션 을 참조 하세요 .

MongoDB 5.0부터 와일드카드 인덱스는 생성 후 정규화되며, wildcardProjection 필드가 Express 이에 상응하는 필터를 하지 않는 한 동일한 키 패턴 을 사용하여 여러 와일드카드 인덱스를 생성할 수 있습니다.

예를 들어 와일드카드 인덱스를 생성합니다.

db.books.createIndex( { "$**" : 1 }, { wildcardProjection : {a: 1, "b.c": 1 } } )

db.collection.getIndexes() 메서드를 사용하여 인덱스를 확인합니다.

db.books.getIndexes()

결과는 정규화된 형식으로 표시됩니다.

{ v: 2, key: { _id: 1 }, name: '_id_' },
{
v: 2,
key: { '$**': 1 },
name: '$**_1',
wildcardProjection: { a: true, b: { c: true }, _id: false }
}
  • 와일드카드 인덱스는 주어진 쿼리 조건자에서 최대 하나 의 필드를 지원할 수 있습니다. 와일드카드 인덱스 쿼리 지원에 대한 자세한 내용은 와일드카드 인덱스 쿼리/정렬 지원을 참조하세요.

  • 와일드카드 인덱스를 생성하려면 mongod featureCompatibilityVersion4.2 여야 합니다. fCV 설정에 대한 지침은 MongoDB 5.0 배포에서 기능 호환성 버전 설정을 참조하세요.

  • 와일드카드 인덱스는 기본적으로 _id 필드를 생략합니다. 와일드카드 인덱스에 _id 필드를 포함하려면 와일드카드 프로젝트 문서에 명시적으로 포함해야 합니다(예: { "_id" : 1 }).

  • 컬렉션에 여러 개의 와일드카드 인덱스를 만들 수 있습니다.

  • 와일드카드 인덱스는 collection의 다른 인덱스와 동일한 필드를 포함할 수 있습니다.

  • 와일드카드 인덱스는 희소 인덱스(sparse indexes) 로 분류되며, 인덱스된 필드가 있는 문서에 대한 항목만 포함합니다. 이는 인덱스 필드에 null 값이 포함되어 있더라도 마찬가지입니다.

와일드카드 인덱스는 객체(예: 내장된 문서) 또는 배열인 필드를 인덱싱할 때 특정 동작을 합니다.

  • 필드가 객체인 경우 와일드카드 인덱스는 객체로 내려가 그 내용을 인덱싱합니다. 와일드카드 인덱스는 발견되는 추가로 내장된 문서로 계속 내려갑니다.

  • 필드가 배열인 경우 와일드카드 인덱스는 배열을 순회하고 각 요소를 인덱싱합니다.

    • 배열의 요소가 객체인 경우 와일드카드 인덱스는 위에서 설명한 대로 객체로 내려가 해당 내용을 인덱싱합니다.

    • 요소가 배열, 즉 상위 배열 내에 직접 포함된 배열인 경우 와일드카드 인덱스는 포함된 배열을 순회하지 않고 전체 배열을 단일 값으로 인덱싱합니다.

  • 다른 모든 필드의 경우 기본(비객체/배열) 값을 인덱스에 기록합니다.

와일드카드 인덱스는 기본 값(즉, 객체나 배열이 아닌 필드)에 도달할 때까지 추가로 중첩된 객체 또는 배열을 계속 순회합니다. 그런 다음 해당 필드의 전체 경로와 함께 이 기본 값을 인덱싱합니다.

예를 들어 다음 문서를 살펴보세요.

{
"parentField" : {
"nestedField" : "nestedValue",
"nestedObject" : {
"deeplyNestedField" : "deeplyNestedValue"
},
"nestedArray" : [
"nestedArrayElementOne",
[ "nestedArrayElementTwo" ]
]
}
}

parentField 가 포함된 와일드카드 인덱스는 다음 항목을 기록합니다.

  • "parentField.nestedField" : "nestedValue"

  • "parentField.nestedObject.deeplyNestedField" : "deeplyNestedValue"

  • "parentField.nestedArray" : "nestedArrayElementOne"

  • "parentField.nestedArray" : ["nestedArrayElementTwo"]

parentField.nestedArray 의 레코드에는 각 요소의 배열 위치가 포함되어 있지 않습니다. 와일드카드 인덱스는 요소를 인덱스에 기록할 때 배열 요소 위치를 무시합니다. 와일드카드 인덱스는 명시적 배열 인덱스를 포함하는 쿼리를 계속 지원할 수 있습니다. 자세한 내용 은 명시적 배열 인덱스를 사용한 쿼리를 참조하세요.

중첩된 객체를 사용한 와일드카드 인덱스 동작에 대한 자세한 내용은 중첩된 객체를 참조하세요 .

중첩 배열을 사용한 와일드카드 인덱스 동작에 대한 자세한 내용은 중첩 배열을 참조하세요 .

와일드카드 인덱스는 중첩된 객체를 만나면 객체로 내려가 내용을 인덱싱합니다. 예를 들면 다음과 같습니다.

{
"parentField" : {
"nestedField" : "nestedValue",
"nestedArray" : ["nestedElement"]
"nestedObject" : {
"deeplyNestedField" : "deeplyNestedValue"
}
}
}

parentField 가 포함된 와일드카드 인덱스는 객체로 내려가 해당 콘텐츠를 탐색하고 인덱싱합니다.

  • 자체가 객체인 각 필드(즉, 내장된 문서)에 대해 객체로 내려가서 해당 내용을 인덱싱합니다.

  • 배열인 각 필드에 대해 배열을 순회하고 해당 내용을 인덱싱합니다.

  • 다른 모든 필드의 경우 기본(비객체/배열) 값을 인덱스에 기록합니다.

와일드카드 인덱스는 기본 값(즉, 객체나 배열이 아닌 필드)에 도달할 때까지 추가로 중첩된 객체 또는 배열을 계속 순회합니다. 그런 다음 해당 필드의 전체 경로와 함께 이 기본 값을 인덱싱합니다.

샘플 문서가 주어지면 와일드카드 인덱스는 다음 기록을 인덱스에 추가합니다.

  • "parentField.nestedField" : "nestedValue"

  • "parentField.nestedObject.deeplyNestedField" : "deeplyNestedValue"

  • "parentField.nestedArray" : "nestedElement"

중첩 배열을 사용한 와일드카드 인덱스 동작에 대한 자세한 내용은 중첩 배열을 참조하세요 .

와일드카드 인덱스는 중첩 배열을 발견하면 배열을 탐색하여 해당 요소를 인덱싱하려고 시도합니다. 배열 자체가 상위 배열(예: 내장된 배열)의 요소인 경우 와일드카드 인덱스는 대신 배열의 내용을 탐색하는 대신 전체 배열을 값으로 기록합니다. 예를 들면 다음과 같습니다.

{
"parentArray" : [
"arrayElementOne",
[ "embeddedArrayElement" ],
"nestedObject" : {
"nestedArray" : [
"nestedArrayElementOne",
"nestedArrayElementTwo"
]
}
]
}

parentArray 가 포함된 와일드카드 인덱스는 배열로 내려가 해당 내용을 탐색하고 인덱싱합니다.

  • 배열인 각 요소(예: 내장된 배열)에 대해 전체 배열을 값으로 인덱스합니다.

  • 객체인 각 요소에 대해 객체로 내려가 해당 내용을 탐색하고 인덱싱합니다.

  • 다른 모든 필드의 경우 기본(비객체/배열) 값을 인덱스에 기록합니다.

와일드카드 인덱스는 기본 값(즉, 객체나 배열이 아닌 필드)에 도달할 때까지 추가로 중첩된 객체 또는 배열을 계속 순회합니다. 그런 다음 해당 필드의 전체 경로와 함께 이 기본 값을 인덱싱합니다.

샘플 문서가 주어지면 와일드카드 인덱스는 다음 기록을 인덱스에 추가합니다.

  • "parentArray" : "arrayElementOne"

  • "parentArray" : ["embeddedArrayElement"]

  • "parentArray.nestedObject.nestedArray" : "nestedArrayElementOne"

  • "parentArray.nestedObject.nestedArray" : "nestedArrayElementTwo"

parentField.nestedArray 의 레코드에는 각 요소의 배열 위치가 포함되어 있지 않습니다. 와일드카드 인덱스는 요소를 인덱스에 기록할 때 배열 요소 위치를 무시합니다. 와일드카드 인덱스는 명시적 배열 인덱스를 포함하는 쿼리를 계속 지원할 수 있습니다. 자세한 내용 은 명시적 배열 인덱스를 사용한 쿼리를 참조하세요.

다음도 참조하세요.

MongoDB 5.0.16 부터 wildcardProjection 필드는 제출된 형식으로 인덱스 프로젝션을 저장합니다. 이전 버전의 서버에서는 프로젝션을 정규화된 형식으로 저장했을 수 있습니다.

서버는 인덱스를 동일한 방식으로 사용하지만 listIndexesdb.collection.getIndexes() 명령의 출력에 차이가 있을 수 있습니다.

  • 와일드카드 인덱스를 사용하여 collection을 샤딩할 수 없습니다. 샤딩하려는 필드에 와일드카드가 아닌 인덱스를 생성합니다. 샤드 키 선택에 대한 자세한 내용은 샤드 키를 참조하세요 .

  • 복합 인덱스 는 생성할 수 없습니다.

  • 와일드카드 인덱스에는 다음 속성을 지정할 수 없습니다.

  • 와일드카드 구문을 사용하여 다음 인덱스 유형을 생성할 수 없습니다.

중요

와일드카드 인덱스는 와일드카드 텍스트 인덱스와 구별되며 호환되지 않습니다. 와일드카드 인덱스는 $text 연산자를 사용하는 쿼리를 지원할 수 없습니다.

와일드카드 인덱스 생성 제한에 대한 전체 문서는 호환되지 않는 인덱스 유형 또는 속성을 참조하세요.

와일드카드 인덱스는 다음이 모두 참인 경우에만 해당 쿼리 를 지원할 수 있습니다.

  • 쿼리 플래너는 쿼리 조건자를 충족하기 위해 와일드카드 인덱스를 선택합니다.

  • 쿼리 조건자는 와일드카드 인덱스가 적용되는 필드를 정확히 하나만 지정합니다.

  • 프로젝션은 _id 를 명시적으로 제외하고 쿼리 필드 포함합니다.

  • 지정된 쿼리 필드는 절대 배열이 아닙니다.

employees collection에 다음과 같은 와일드카드 인덱스가 있다고 가정해 봅시다.

db.products.createIndex( { "$**" : 1 } )

다음 작업은 단일 필드 lastName에 대해 쿼리하고 결과 문서에서 다른 모든 필드를 프로젝트합니다.

db.products.find(
{ "lastName" : "Doe" },
{ "_id" : 0, "lastName" : 1 }
)

지정된 lastName 가 배열이 아니라는 가정 하에 MongoDB는 $** 와일드카드 인덱스를 사용하여 해당 쿼리를 지원할 수 있습니다.

와일드카드 인덱스는 최대 하나 의 쿼리 조건자 필드를 지원할 수 있습니다. 즉:

  • MongoDB는 와일드카드가 아닌 인덱스를 사용하여 쿼리 조건자의 한 부분을 충족하고 와일드카드 인덱스를 사용하여 다른 부분을 충족할 수 없습니다.

  • MongoDB는 하나의 와일드카드 인덱스를 사용하여 쿼리 술어의 한 부분을 충족하고 다른 와일드카드 인덱스를 사용하여 다른 부분을 충족할 수 없습니다.

  • 단일 와일드카드 인덱스가 여러 쿼리 필드를 지원할 수 있더라도 MongoDB는 와일드카드 인덱스를 사용하여 쿼리 필드 중 하나만 지원할 수 있습니다. 나머지 모든 필드는 인덱스 없이 해결됩니다.

그러나 MongoDB는 쿼리 $or 또는 애그리게이션 $or 연산자의 각 독립적인 인수를 충족하기 위해 동일한 와일드카드 인덱스를 사용할 수 있습니다.

MongoDB는 다음 사항이 모두 참인 경우에만 를 충족하기 위해 와일드카드 인덱스를 사용할 수 있습니다. sort()

  • 쿼리 플래너는 쿼리 조건자를 충족하기 위해 와일드카드 인덱스를 선택합니다.

  • sort() 는 쿼리 조건자 필드 지정합니다.

  • 지정된 필드는 배열이 아닙니다.

위의 조건이 충족되지 않으면 MongoDB는 정렬에 와일드카드 인덱스를 사용할 수 없습니다. MongoDB는 쿼리 조건자의 인덱스와 다른 인덱스가 필요한 sort() 작업을 지원하지 않습니다. 자세한 내용은 인덱스 교차 및 정렬을 참조하세요.

products collection에 다음과 같은 와일드카드 인덱스가 있다고 가정해 봅시다.

db.products.createIndex( { "product_attributes.$**" : 1 } )

다음 작업은 단일 필드 product_attributes.price 를 쿼리하고 동일한 필드를 정렬합니다.

db.products.find(
{ "product_attributes.price" : { $gt : 10.00 } },
).sort(
{ "product_attributes.price" : 1 }
)

지정된 price 가 배열이 아니라고 가정하면 MongoDB는 product_attributes.$** 와일드카드 인덱스를 사용하여 find()sort() 을 모두 충족할 수 있습니다.

와일드카드 인덱스는 다음 쿼리 패턴을 지원할 수 없습니다 .

  • 필드가 존재하지 않는지 확인하는 쿼리

  • 필드가 문서 또는 배열과 같은지 확인하는 쿼리

  • 필드가 null과 같은지 확인하는 쿼리

자세한 내용은 지원되지 않는 쿼리 및 애그리게이션 패턴을 참조하세요.

MongoDB 와일드카드 인덱스는 인덱싱 중에 배열에 지정된 요소의 배열 위치를 기록하지 않습니다. 그러나 MongoDB는 하나 이상의 명시적 배열 인덱스(예: parentArray.0.nestedArray.0)가 있는 필드 경로를 포함하는 쿼리에 답변하기 위해 와일드카드 인덱스를 선택할 수 있습니다. 연속된 각 중첩 배열에 대한 인덱스 경계를 정의하는 것이 점점 더 복잡해지기 때문에 MongoDB는 경로에 8 개 이상의 명시적 배열 인덱스가 포함되어 있는 경우 쿼리에서 지정된 필드 경로에 응답하는 데 와일드카드 인덱스를 고려하지 않습니다. MongoDB는 여전히 쿼리의 다른 필드 경로에 응답하기 위해 와일드카드 인덱스를 고려할 수 있습니다.

예를 들면 다음과 같습니다.

{
"parentObject" : {
"nestedArray" : [
"elementOne",
{
"deeplyNestedArray" : [ "elementTwo" ]
}
]
}
}

MongoDB는 다음 쿼리를 충족하기 위해 parentObject 가 포함된 와일드카드 인덱스를 선택할 수 있습니다.

  • "parentObject.nestedArray.0" : "elementOne"

  • "parentObject.nestedArray.1.deeplyNestedArray.0" : "elementTwo"

쿼리 조건자의 지정된 필드 경로가 8개 이상의 명시적 배열 인덱스를 지정하는 경우 MongoDB는 해당 필드 경로에 응답할 때 와일드카드 인덱스를 고려하지 않습니다. 대신 MongoDB는 쿼리에 답변하기 위해 다른 적합한 인덱스를 선택 하거나 collection 스캔을 수행합니다.

와일드카드 인덱스 자체는 문서를 인덱싱하는 동안 문서를 탐색하는 깊이에 제한이 없습니다. 이 제한은 정확한 배열 인덱스를 명시적으로 지정하는 쿼리에만 적용됩니다. 명시적인 배열 인덱스 없이 동일한 쿼리를 실행함으로써 MongoDB는 와일드카드 인덱스를 선택하여 쿼리에 답변할 수 있습니다.

  • "parentObject.nestedArray" : "elementOne"

  • "parentObject.nestedArray.deeplyNestedArray" : "elementTwo"

다음도 참조하세요.

돌아가기

자체 관리 배포서버에서 스캔되는 텍스트 인덱스 항목 수 제한

다음

와일드카드 인덱스 제한