MongoDB
 sql >> Cơ Sở Dữ Liệu >  >> NoSQL >> MongoDB

Loại trừ các trường cụ thể trong chỉ mục ký tự đại diện trong MongoDB

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.


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. MongoDB có vấn đề kết nối lại hay tôi làm sai?

  2. So sánh mongoose _id và string

  3. Làm thế nào để điền các thực thể lồng nhau vào mongoose?

  4. Tạo chỉ mục ký tự đại diện trong MongoDB

  5. Có tùy chọn nào để giới hạn việc sử dụng bộ nhớ mongodb không?