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

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

Có một số cách để tạo chỉ mục trong MongoDB và từ MongoDB 4.2, chúng ta có thể tạo chỉ mục ký tự đại diện.

Chỉ mục ký tự đại diện có thể được coi là một loại bộ lọc tự động khớp với bất kỳ trường, tài liệu con hoặc mảng nào trong một bộ sưu tập và sau đó lập chỉ mục các kết quả phù hợp đó.

Điều này có thể hữu ích nếu tài liệu của bạn chứa dữ liệu phi cấu trúc với các trường khác nhau trong các phân cấp khác nhau. Trong những trường hợp như vậy, không có cách nào để dự đoán chỉ mục nên là gì, vì bạn không biết dữ liệu nào sẽ có trong mỗi tài liệu.

Chỉ mục ký tự đại diện có thể hữu ích với dữ liệu phi cấu trúc như vậy, vì chúng lập chỉ mục tất cả các giá trị vô hướng của trường, tự động đệ quy thành bất kỳ tài liệu con hoặc mảng nào và lập chỉ mục tất cả các trường vô hướng trong tài liệu con / mảng.

Bộ sưu tập mẫu

Chỉ mục ký tự đại diện không dành cho mọi bộ sưu tập. Bạn sẽ chỉ tạo chỉ mục ký tự đại diện trên một số bộ sưu tập nhất định với các tài liệu chứa dữ liệu phi cấu trúc với các trường khác nhau trong các phân cấp khác nhau.

Dưới đây là ví dụ về bộ sưu tập có tên pets đó có thể là một ứng cử viên tốt cho chỉ mục ký tự đại diện:

{
	"_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")
	}
}

Mỗi tài liệu trong số 3 tài liệu trong bộ sưu tập này có một details nhưng chúng chứa các trường khác nhau trong trường đó. Nó không nhất quán. Điều này thường gây khó khăn cho việc tạo chỉ mục vì chúng tôi không biết những trường nào sẽ có trong mỗi tài liệu. Chúng tôi có thể sẽ cần tạo nhiều chỉ mục, sau khi phân tích cẩn thận các cấu trúc tài liệu có thể có.

May mắn thay, chúng tôi có thể tạo chỉ mục ký tự đại diện.

Nhưng trước tiên, hãy xem kế hoạch truy vấn có thể trông như thế nào khi truy vấn một trong các trường đó. Hãy tưởng tượng chúng ta muốn tìm ra chú chó nào đã nhận được giải thưởng “Chú chó chạy nhanh nhất” tại cuộc thi Marathon ở New York. Chúng tôi có thể làm như sau:

db.pets.find( { "details.awards.New York Marathon" : "Fastest Dog" } )

Và nếu chúng tôi muốn kiểm tra kế hoạch truy vấn, chúng tôi có thể thêm explain() cuối cùng:

db.pets.find( { "details.awards.New York Marathon" : "Fastest Dog" } ).explain()

Trả về như sau:

{
	"queryPlanner" : {
		"plannerVersion" : 1,
		"namespace" : "PetHotel.pets",
		"indexFilterSet" : false,
		"parsedQuery" : {
			"details.awards.New York Marathon" : {
				"$eq" : "Fastest Dog"
			}
		},
		"queryHash" : "EC0D5185",
		"planCacheKey" : "EC0D5185",
		"winningPlan" : {
			"stage" : "COLLSCAN",
			"filter" : {
				"details.awards.New York Marathon" : {
					"$eq" : "Fastest Dog"
				}
			},
			"direction" : "forward"
		},
		"rejectedPlans" : [ ]
	},
	"ok" : 1
}

Điều này cho chúng tôi biết rằng nó sẽ thực hiện quét bộ sưu tập (COLLSCAN), có nghĩa là nó phải quét qua mọi tài liệu đang tìm kiếm trường.

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

Dưới đây là ví dụ về cách tạo chỉ mục ký tự đại diện cho bộ sưu tập ở trên.

db.pets.createIndex({ "details.$**": 1 });

Đầu ra:

{
	"createdCollectionAutomatically" : false,
	"numIndexesBefore" : 1,
	"numIndexesAfter" : 2,
	"ok" : 1
}

Đó là nó. Chỉ mục ký tự đại diện đã được tạo.

Để tạo chỉ mục ký tự đại diện, chúng tôi đã sử dụng tên trường mà chúng tôi muốn tạo chỉ mục trên đó (trong trường hợp này là details ), sau đó chúng tôi thêm trường đó bằng dấu chấm (. ), và sau đó là phần quan trọng, $** một phần.

$** chỉ định rằng một chỉ mục ký tự đại diện nên được tạo từ trường này và tất cả các tài liệu con của nó.

Tiền tố $** với details giới hạn phạm vi của chỉ mục ký tự đại diện chỉ với details trường.

Bây giờ, hãy kiểm tra lại kế hoạch truy vấn cho truy vấn nói trên:

db.pets.find( { "details.awards.New York Marathon" : "Fastest Dog" } ).explain()

Kết quả:

{
	"queryPlanner" : {
		"plannerVersion" : 1,
		"namespace" : "PetHotel.pets",
		"indexFilterSet" : false,
		"parsedQuery" : {
			"details.awards.New York Marathon" : {
				"$eq" : "Fastest Dog"
			}
		},
		"queryHash" : "EC0D5185",
		"planCacheKey" : "7DFA23ED",
		"winningPlan" : {
			"stage" : "FETCH",
			"inputStage" : {
				"stage" : "IXSCAN",
				"keyPattern" : {
					"$_path" : 1,
					"details.awards.New York Marathon" : 1
				},
				"indexName" : "details.$**_1",
				"isMultiKey" : false,
				"multiKeyPaths" : {
					"$_path" : [ ],
					"details.awards.New York Marathon" : [ ]
				},
				"isUnique" : false,
				"isSparse" : false,
				"isPartial" : false,
				"indexVersion" : 2,
				"direction" : "forward",
				"indexBounds" : {
					"$_path" : [
						"[\"details.awards.New York Marathon\", \"details.awards.New York Marathon\"]"
					],
					"details.awards.New York Marathon" : [
						"[\"Fastest Dog\", \"Fastest Dog\"]"
					]
				}
			}
		},
		"rejectedPlans" : [ ]
	},
	"ok" : 1
}

Lần này quét thu thập (COLLSCAN) đã được thay thế bằng quét chỉ mục (IXSCAN) trên chỉ mục ký tự đại diện mới được tạo của chúng tôi.

Mỗi trường trong details của chúng tôi trường đã được lập chỉ mục dưới dạng đường dẫn / giá trị và có một mục nhập trong chỉ mục cho mọi trường trong hệ thống phân cấp. Trong đó giá trị trường là một tài liệu phụ (chẳng hạn như. awards của chúng tôi trường), chỉ mục đã đi xuống tài liệu con và lặp lại quá trình.

Tạo chỉ mục ký tự đại diện trên tất cả các đường dẫn trường

Trong ví dụ trước, chúng tôi đã tạo chỉ mục ký tự đại diện trên một đường dẫn trường. Có thể tạo chỉ mục ký tự đại diện trên tất cả các đường dẫn trường bằng cách sử dụng $** mà không đặt trước nó bằng một trường.

Ví dụ, chúng tôi có thể đã làm điều này:

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

Điều đó sẽ tạo ra một chỉ mục ký tự đại diện trên tất cả các đường dẫn trường.

Trên thực tế, điều đó không hoàn toàn đúng. Theo mặc định, chỉ mục ký tự đại diện không được tạo trên _id đồng ruộng. Để bao gồm _id , bạn sẽ cần đưa nó vào một wildcardProjection tài liệu.

Không thể tạo chỉ mục ký tự đại diện? Kiểm tra Cài đặt này.

mongod featureCompatibilityVersion ít nhất phải là 4.2 để tạo chỉ mục ký tự đại diện.

Bạn có thể kiểm tra cài đặt này bằng mã sau:

db.adminCommand( 
    { 
        getParameter: 1, 
        featureCompatibilityVersion: 1 
    } 
)

Bạn có thể đặt nó bằng setFeatureCompatibilityVersion lệnh:

db.adminCommand( { setFeatureCompatibilityVersion: "4.4" } )

setFeatureCompatibilityVersion lệnh cần được chạy trong admin cơ sở dữ liệu.


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. MongoDB $ kéo

  2. MongoDB:Đang cập nhật subocument

  3. MongoDB:Tìm tài liệu con trong tham số so khớp mảng

  4. Sao lưu và khôi phục MongoDB bằng MongoDump

  5. cách quản lý trường _id khi sử dụng POCO với trình điều khiển mongodb c #