부분 인덱스
부분 인덱스는 지정된 필터 기준을 충족하는 컬렉션의 문서를 색인합니다. 부분 인덱스 기능은 Amazon DocumentDB 5.0 인스턴스 기반 클러스터에서 지원됩니다.
부분 인덱스 생성
부분 인덱스를 생성하려면 partialFilterExpression
옵션과 함께 createIndex()
메서드를 사용합니다. 예를 들어, 다음 작업은 isDelivered
필드가 OrderID
true인 문서를 색인하는 명령 컬렉션에 고유한 복합 인덱스를 생성합니다.
db.orders.createIndex( {"category": 1, "CustomerId": 1, "OrderId": 1}, {"unique": true, "partialFilterExpression": {"$and": [ {"OrderId": {"$exists": true}}, {"isDelivered": {"$eq": false}} ]} } )
지원되는 연산자
$eq
$exists
$and(최상위 수준에서만)
$gt/$gte/$lt/$lte(인덱스 스캔은 쿼리에 예측된 필터가 부분 필터 식과 정확히 일치하는 경우에만 사용됨)(제한 사항 참조)
부분 인덱스를 사용한 쿼리
부분 인덱스를 사용하면 다음 쿼리 패턴을 사용할 수 있습니다.
-
쿼리 조건자는 부분 인덱스 필터 식과 정확히 일치합니다.
db.orders.find({"$and": [ {"OrderId": {"$exists": true}}, {"isDelivered": {"$eq": false}} ]}).explain()
-
쿼리 필터의 예상 결과는 부분 필터의 논리적 하위 집합입니다.
db.orders.find({"$and": [ {"OrderId": {"$exists": true}}, {"isDelivered": {"$eq": false}}, {"OrderAmount": {"$eq": "5"}} ]}).explain()
-
쿼리의 하위 조건자는 다른 인덱스와 함께 사용할 수 있습니다.
db.orders.createIndex({"anotherIndex":1}) db.orders.find({ "$or": [ {"$and": [ {"OrderId": {"$exists": true}}, {"isDelivered": {"$eq": false}} ]}, {"anotherIndex": {"$eq": 5}} ] }).explain()
참고
쿼리 실행 계획기는 효율적인 경우 인덱스 스캔 대신 컬렉션 스캔을 사용하도록 선택할 수 있습니다. 이는 일반적으로 컬렉션의 많은 부분을 반환하는 매우 작은 컬렉션 또는 쿼리에 표시됩니다.
부분 인덱스 기능
부분 인덱스 나열
getIndex
작업을 사용하여 partialFilterExpression으로 부분 인덱스를 나열합니다. 예를 들어, 발행된 getIndex
작업은 키, 이름 및 partialfilterExpressions 필드가 포함된 부분 인덱스를 나열합니다.
db.orders.getIndexes()
이 예제는 다음 출력을 반환합니다.
[
{
"v" : 4,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "ecommerceApp.orders"
},
{
"v" : 4,
"unique" : true,
"key" : {
"category" : 1,
"" : 1,
"CustomerId" : 1,
"OrderId" : 1
},
"name" : "category_1_CustID_1_OrderId_1",
"ns" : "ecommerceApp.orders",
"partialFilterExpression" : {
"$and" : [
{"OrderId": {"$exists": true}},
{"isDelivered": {"$eq": false}}
]
}
}
]
동일한 키에 대한 여러 부분 필터 식: 순서
동일한 필드 조합(키: 순서)에 대해 서로 다른 부분 인덱스를 생성할 수 있습니다. 이러한 인덱스의 이름은 달라야 합니다.
db.orders.createIndex( {"OrderId":1}, { name:"firstPartialIndex", partialFilterExpression:{"OrderId":{"$exists": true}} } )
db.orders.createIndex( {"OrderId":1}, { name:"secondPartialIndex", partialFilterExpression:{"OrderId":{"$gt": 1000}} } )
getIndexes
작업을 실행하여 컬렉션의 모든 인덱스를 나열합니다.
db.orders.getIndexes()
이러한 예제는 다음 출력을 반환합니다.
[
{
"v" : 4,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "ecommerceApp.orders"
},
{
"v" : 4,
"key" : {
"OrderId" : 1
},
"name" : "firstPartialIndex",
"ns" : "ecommerceApp.orders",
"partialFilterExpression" : {"OrderId":{"$exists": true}}
},
{
"v" : 4,
"key" : {
"OrderId" : 1
},
"name" : "secondPartialIndex",
"ns" : "ecommerceApp.orders",
"partialFilterExpression" : {"OrderId":{"$gt": 1000}}
}
]
중요
인덱스 이름은 달라야 하며 이름으로만 삭제해야 합니다.
부분 및 TTL 속성이 있는 인덱스
인덱스 생성 중에 partialFilterExpression
및 expireAfterSeconds
옵션을 모두 지정하여 부분 및 TTL 속성을 가진 인덱스를 생성할 수도 있습니다. 이렇게 하면 컬렉션에서 이제 제거되는 문서를 더 잘 제어할 수 있습니다.
예를 들어 특정 기간 이후에 삭제할 문서를 식별하는 TTL 인덱스가 있을 수 있습니다. 이제 부분 인덱스 옵션을 사용하여 문서를 삭제하는 시기에 대한 추가 조건을 지정할 수 있습니다.
db.orders.createIndex( { "OrderTimestamp": 1 }, { expireAfterSeconds: 3600 , partialFilterExpression: { "isDelivered": { $eq: true } } } )
이 예제는 다음 출력을 반환합니다.
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1,
"operationTime" : Timestamp(1234567890, 1)
}
getIndexes
작업을 실행하여 컬렉션에 존재하는 인덱스를 나열합니다.
db.orders.getIndexes() [ { "v" : 4, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "test.orders" }
이 예제는 다음 출력을 반환합니다.
[
{
"v": 4,
"key": {
"_id": 1
},
"name": "_id_",
"ns": "ecommerceApp.orders"
},
{
"v": 4,
"key": {
"OrderTimestamp": 1
},
"name": "OrderTimestamp_1",
"ns": "ecommerceApp.orders",
"partialFilterExpression": {
"isDelivered": {
"$eq": true
}
},
"expireAfterSeconds": 3600
}
]
부분 인덱스 제한 사항
다음 제한 사항이 부분 인덱스 기능에 적용됩니다.
-
Amazon DocumentDB의 불평등 쿼리는 쿼리 필터 예측이
partialFilterExpression
과 정확히 일치하고 동일한 데이터 유형인 경우에만 부분 인덱스를 사용합니다.참고
위 사례에 대해 IXSCAN을 강제로 적용하는 데도
$hint
를 사용할 수 없습니다.다음 예제에서
partialFilterExpression
은field1
에만 적용되고field2
에는 적용되지 않습니다.db.orders.createIndex( {"OrderAmount": 1}, {"partialFilterExpression": { OrderAmount : {"$gt" : 5}}} ) db.orders.find({OrderAmount : {"$gt" : 5}}) // Will use partial index db.orders.find({OrderAmount : {"$gt" : 6}}) // Will not use partial index db.orders.find({OrderAmount : {"$gt" : Decimal128(5.00)}}) // Will not use partial index
-
배열 연산자가
partialFilterExpression
은 지원되지 않습니다. 다음 작업은 오류를 생성합니다.db.orders.createIndex( {"CustomerId":1}, {'partialFilterExpression': {'OrderId': {'$eq': [1000, 1001, 1002]}}} )
partialFilterExpression 필드에서는 다음 연산자가 지원되지 않습니다.
$all
(배열 연산자)$mod
(배열 연산자)$or
$xor
$not
$nor
필터 식과 필터의 데이터 유형은 동일해야 합니다.