Khi bạn tạo chỉ mục ký tự đại diện trong MongoDB, bạn có tùy chọn chỉ định một trường, tất cả các trường hoặc chỉ một số trường.
Bạn cũng có tùy chọn loại trừ các trường nhất định. Nói cách khác, bạn có thể chỉ định tất cả các trường ngoại trừ cho một hoặc nhiều trường cụ thể.
Bạn có thể sử dụng wildcardProjection
để bao gồm hoặc loại trừ các đường dẫn trường cụ thể khỏi chỉ mục ký tự đại diện. Bài viết này trình bày một ví dụ về loại trừ các trường cụ thể trong chỉ mục ký tự đại diện.
Tài liệu Ví dụ
Giả sử chúng ta có một bộ sưu tập có tên là pets
với các tài liệu sau:
{ "_id" : 1, "name" : "Wag", "details" : { "type" : "Dog", "weight" : 20, "awards" : { "Florida Dog Awards" : "Top Dog", "New York Marathon" : "Fastest Dog", "Sumo 2020" : "Biggest Dog" } } } { "_id" : 2, "name" : "Fetch", "details" : { "born" : ISODate("2020-06-22T14:00:00Z"), "color" : "Black" } } { "_id" : 3, "name" : "Scratch", "details" : { "eats" : [ "Mouse Porridge", "Bird Soup", "Caviar" ], "type" : "Cat", "born" : ISODate("2020-12-19T14:00:00Z") } }
Chúng tôi có thể tạo chỉ mục ký tự đại diện trên toàn bộ tập hợp, đồng thời loại trừ các trường nhất định.
Tạo chỉ mục
Đây là một ví dụ:
db.pets.createIndex(
{ "$**" : 1 },
{
"wildcardProjection" : {
"details.awards" : 0,
"details.eats" : 0
}
}
)
Đầu ra:
{ "createdCollectionAutomatically" : false, "numIndexesBefore" : 1, "numIndexesAfter" : 2, "ok" : 1 }
{ "$**" : 1 }
một phần là thứ tạo ra chỉ mục ký tự đại diện và wildcardProjection
part là phần chỉ định những trường nào cần loại trừ. Trong trường hợp này, chúng tôi đã loại trừ details.awards
và trường details.eats
đồng ruộng. Cung cấp cho chúng giá trị 0
loại trừ chúng khỏi chỉ mục một cách rõ ràng.
Xem chỉ mục
Chúng tôi có thể xem các chỉ mục trên bộ sưu tập bằng cách gọi getIndexes()
phương pháp:
db.pets.getIndexes()
Kết quả:
[ { "v" : 2, "key" : { "_id" : 1 }, "name" : "_id_" }, { "v" : 2, "key" : { "$**" : 1 }, "name" : "$**_1", "wildcardProjection" : { "details.awards" : 0, "details.eats" : 0 } } ]
Chúng ta có thể thấy rằng có hai chỉ mục.
- Chỉ mục đầu tiên nằm trên
_id
đồng ruộng. Điều này được tạo khi bộ sưu tập được tạo (MongoDB tạo một chỉ mục duy nhất trên trường _id trong quá trình tạo bộ sưu tập). - Chỉ mục thứ hai là chỉ mục ký tự đại diện của chúng tôi. Chúng ta có thể thấy rằng nó được tự động đặt tên là
$**_1
và nó bao gồm các trường mà chúng tôi đã chỉ định cùng với giá trị0
, có nghĩa là chúng bị loại trừ rõ ràng khỏi chỉ mục.
Kiểm tra chỉ mục
Chúng tôi cũng có thể chạy một số truy vấn để xem liệu chỉ mục của chúng tôi có được sử dụng hay không và liệu các trường bị loại trừ có thực sự bị loại trừ hay không
Truy vấn sau nên sử dụng chỉ mục:
db.pets.find( { "details.type" : "Dog" } )
Nó nên sử dụng chỉ mục vì chúng tôi không loại trừ details.type
từ chỉ mục.
Để kiểm tra điều này, chúng tôi có thể thêm explain()
phương pháp để xem kế hoạch truy vấn:
db.pets.find( { "details.type" : "Dog" } ).explain()
Kết quả:
{ "queryPlanner" : { "plannerVersion" : 1, "namespace" : "PetHotel.pets", "indexFilterSet" : false, "parsedQuery" : { "details.type" : { "$eq" : "Dog" } }, "queryHash" : "F1C5286F", "planCacheKey" : "5326DE93", "winningPlan" : { "stage" : "FETCH", "inputStage" : { "stage" : "IXSCAN", "keyPattern" : { "$_path" : 1, "details.type" : 1 }, "indexName" : "$**_1", "isMultiKey" : false, "multiKeyPaths" : { "$_path" : [ ], "details.type" : [ ] }, "isUnique" : false, "isSparse" : false, "isPartial" : false, "indexVersion" : 2, "direction" : "forward", "indexBounds" : { "$_path" : [ "[\"details.type\", \"details.type\"]" ], "details.type" : [ "[\"Dog\", \"Dog\"]" ] } } }, "rejectedPlans" : [ ] }, "ok" : 1 }
Chúng tôi có thể thấy rằng nó đã sử dụng quét chỉ mục (IXSCAN) trên chỉ mục của chúng tôi.
Ngược lại với điều này, đây là những gì sẽ xảy ra khi chúng tôi chạy truy vấn trên một trong các trường mà chúng tôi đã loại trừ từ chỉ mục:
db.pets.find( { "details.awards.Florida Dog Awards" : "Top Dog" } ).explain()
Kết quả:
{ "queryPlanner" : { "plannerVersion" : 1, "namespace" : "PetHotel.pets", "indexFilterSet" : false, "parsedQuery" : { "details.awards.Florida Dog Awards" : { "$eq" : "Top Dog" } }, "queryHash" : "16FBC17B", "planCacheKey" : "16FBC17B", "winningPlan" : { "stage" : "COLLSCAN", "filter" : { "details.awards.Florida Dog Awards" : { "$eq" : "Top Dog" } }, "direction" : "forward" }, "rejectedPlans" : [ ] }, "ok" : 1 }
Trong trường hợp này, nó đã quét bộ sưu tập (COLLSCAN), vì vậy, như mong đợi, nó không sử dụng chỉ mục.