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

Tạo chỉ mục nhiều khóa trong MongoDB

Trong MongoDB, khi bạn tạo chỉ mục trên trường chứa một mảng, mảng đó sẽ tự động được tạo dưới dạng chỉ mục nhiều khóa.

Chỉ mục multikey hỗ trợ các truy vấn hiệu quả đối với các trường mảng.

Chỉ mục nhiều khóa có thể được tạo cho các mảng chứa dữ liệu vô hướng (ví dụ:chuỗi, số, v.v.) và các tài liệu lồng nhau.

Ví dụ

Giả sử chúng ta có một bộ sưu tập được gọi là products chứa các tài liệu sau:

{ "_id" : 1, "product" : "Bat", "sizes" : [ "S", "M", "L" ] }
{ "_id" : 2, "product" : "Hat", "sizes" : [ "S", "L", "XL" ] }
{ "_id" : 3, "product" : "Cap", "sizes" : [ "M", "L" ] }

Chúng tôi có thể tạo một chỉ mục nhiều khóa trên bộ sưu tập đó như sau:

db.products.createIndex(
   {
     "sizes": 1
   }
)

Nó giống như tạo một chỉ mục thông thường. Bạn không cần phải chỉ định rõ ràng rằng đó là một chỉ mục đa khóa. MongoDB có thể xác định rằng trường chứa một mảng và do đó tạo nó dưới dạng một chỉ mục đa khóa.

Với các chỉ mục nhiều khóa, MongoDB tạo một khóa chỉ mục cho mỗi phần tử trong mảng.

Chỉ mục đa khóa kết hợp trên tài liệu nhúng

Như đã đề cập, bạn có thể tạo chỉ mục nhiều khóa cho các mảng chứa các tài liệu được nhúng.

Bạn có thể tạo một chỉ mục kết hợp trên các chỉ mục này, để chỉ mục của bạn được tạo dựa trên nhiều trường trong mảng.

Giả sử chúng ta có một bộ sưu tập có tên là restaurants với các tài liệu như thế này:

db.restaurants.insertMany([
   {
    _id: 1,
    name: "The Rat",
    reviews: [{
        name: "Stanley",
        date: "04 December, 2020",
        ordered: "Dinner",
        rating: 1
      },
      {
        name: "Tom",
        date: "04 October, 2020",
        ordered: "Lunch",
        rating: 2
      }]
   },
   {
    _id: 2,
    name: "Yum Palace",
    reviews: [{
        name: "Stacey",
        date: "08 December, 2020",
        ordered: "Lunch",
        rating: 3
      },
      {
        name: "Tom",
        date: "08 October, 2020",
        ordered: "Breakfast",
        rating: 4
      }]
   },
   {
    _id: 3,
    name: "Boardwalk Cafe",
    reviews: [{
        name: "Steve",
        date: "20 December, 2020",
        ordered: "Breakfast",
        rating: 5
      },
      {
        name: "Lisa",
        date: "25 October, 2020",
        ordered: "Dinner",
        rating: 5
      },
      {
        name: "Kim",
        date: "21 October, 2020",
        ordered: "Dinner",
        rating: 5
      }]
   }
])

Chúng tôi có thể tạo một chỉ mục đa khóa kết hợp như thế này:

db.restaurants.createIndex( 
  { 
    "reviews.ordered": 1,
    "reviews.rating": -1
  } 
)

Bây giờ, chỉ mục multikey sẽ được sử dụng bất cứ khi nào chúng tôi chạy các truy vấn liên quan đến các trường đó.

Đây là kế hoạch truy vấn trông như thế nào khi chúng tôi tìm kiếm dựa trên một trong các trường đó:

db.restaurants.find( { "reviews.ordered": "Dinner" } ).explain()

Kết quả:

{
	"queryPlanner" : {
		"plannerVersion" : 1,
		"namespace" : "krankykranes.restaurants",
		"indexFilterSet" : false,
		"parsedQuery" : {
			"reviews.ordered" : {
				"$eq" : "Dinner"
			}
		},
		"queryHash" : "A01226B4",
		"planCacheKey" : "0E761583",
		"winningPlan" : {
			"stage" : "FETCH",
			"inputStage" : {
				"stage" : "IXSCAN",
				"keyPattern" : {
					"reviews.ordered" : 1,
					"reviews.rating" : -1
				},
				"indexName" : "reviews.ordered_1_reviews.rating_-1",
				"isMultiKey" : true,
				"multiKeyPaths" : {
					"reviews.ordered" : [
						"reviews"
					],
					"reviews.rating" : [
						"reviews"
					]
				},
				"isUnique" : false,
				"isSparse" : false,
				"isPartial" : false,
				"indexVersion" : 2,
				"direction" : "forward",
				"indexBounds" : {
					"reviews.ordered" : [
						"[\"Dinner\", \"Dinner\"]"
					],
					"reviews.rating" : [
						"[MaxKey, MinKey]"
					]
				}
			}
		},
		"rejectedPlans" : [ ]
	},
	"ok" : 1
}

Phần đọc IXSCAN nghĩa là nó đã quét chỉ mục. Nếu nó không sử dụng chỉ mục, nó sẽ thực hiện quét bộ sưu tập (COLLSCAN ).

Điều này cũng tương tự khi chúng tôi thực hiện một truy vấn liên quan đến cả hai trường trong chỉ mục:

db.restaurants.find( { "reviews.ordered": "Dinner", "reviews.rating": { $gt: 3 } } ).explain()

Kết quả:

{
	"queryPlanner" : {
		"plannerVersion" : 1,
		"namespace" : "krankykranes.restaurants",
		"indexFilterSet" : false,
		"parsedQuery" : {
			"$and" : [
				{
					"reviews.ordered" : {
						"$eq" : "Dinner"
					}
				},
				{
					"reviews.rating" : {
						"$gt" : 3
					}
				}
			]
		},
		"queryHash" : "C770E210",
		"planCacheKey" : "447B5666",
		"winningPlan" : {
			"stage" : "FETCH",
			"filter" : {
				"reviews.rating" : {
					"$gt" : 3
				}
			},
			"inputStage" : {
				"stage" : "IXSCAN",
				"keyPattern" : {
					"reviews.ordered" : 1,
					"reviews.rating" : -1
				},
				"indexName" : "reviews.ordered_1_reviews.rating_-1",
				"isMultiKey" : true,
				"multiKeyPaths" : {
					"reviews.ordered" : [
						"reviews"
					],
					"reviews.rating" : [
						"reviews"
					]
				},
				"isUnique" : false,
				"isSparse" : false,
				"isPartial" : false,
				"indexVersion" : 2,
				"direction" : "forward",
				"indexBounds" : {
					"reviews.ordered" : [
						"[\"Dinner\", \"Dinner\"]"
					],
					"reviews.rating" : [
						"[MaxKey, MinKey]"
					]
				}
			}
		},
		"rejectedPlans" : [ ]
	},
	"ok" : 1
}

Tuy nhiên, nếu một trong các trường trong truy vấn không được bao gồm trong chỉ mục, thì nó dẫn đến việc quét bộ sưu tập:

db.restaurants.find( { "reviews.name": "Lisa", "reviews.rating": { $gt: 3 } } ).explain()

Kết quả:

{
	"queryPlanner" : {
		"plannerVersion" : 1,
		"namespace" : "krankykranes.restaurants",
		"indexFilterSet" : false,
		"parsedQuery" : {
			"$and" : [
				{
					"reviews.name" : {
						"$eq" : "Lisa"
					}
				},
				{
					"reviews.rating" : {
						"$gt" : 3
					}
				}
			]
		},
		"queryHash" : "49EF83EC",
		"planCacheKey" : "3C60321C",
		"winningPlan" : {
			"stage" : "COLLSCAN",
			"filter" : {
				"$and" : [
					{
						"reviews.name" : {
							"$eq" : "Lisa"
						}
					},
					{
						"reviews.rating" : {
							"$gt" : 3
						}
					}
				]
			},
			"direction" : "forward"
		},
		"rejectedPlans" : [ ]
	},
	"ok" : 1
}


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Lược đồ đúng MongoDB cho dữ liệu tổng hợp

  2. Nhóm MongoDB theo các giá trị trong một trường mảng

  3. MongoDB và C #:Tìm kiếm không phân biệt chữ hoa chữ thường

  4. Toán tử truy vấn MongoDB $ type

  5. Tìm theo id với mgo