sql >> Databasteknik >  >> NoSQL >> MongoDB

Skapa ett Multikey Index i MongoDB

I MongoDB, när du skapar ett index på ett fält som innehåller en array, skapas det automatiskt som ett flernyckelindex.

Multikey-index stöder effektiva frågor mot matrisfält.

Multikey-index kan skapas för arrayer som innehåller skalär data (t.ex. strängar, siffror, etc.) och kapslade dokument.

Exempel

Anta att vi har en samling som heter products som innehåller följande dokument:

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

Vi kan skapa ett multikey-index för den samlingen så här:

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

Det är precis som att skapa ett vanligt index. Du behöver inte uttryckligen ange att det är ett flernyckelindex. MongoDB kan avgöra att fältet innehåller en array och skapar det därför som ett multikey-index.

Med multikey-index skapar MongoDB en indexnyckel för varje element i arrayen.

Sammansatt multikeyindex på inbäddade dokument

Som nämnts kan du skapa flernyckelindex för arrayer som innehåller inbäddade dokument.

Du kan skapa ett sammansatt index på dessa, så att ditt index skapas mot flera fält i arrayen.

Anta att vi har en samling som heter restaurants med dokument som detta:

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
      }]
   }
])

Vi skulle kunna skapa ett sammansatt multikey-index så här:

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

Nu kommer flernyckelindexet att användas när vi kör frågor som involverar dessa fält.

Så här ser frågeplanen ut när vi söker mot ett av dessa fält:

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

Resultat:

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

Den del som läser IXSCAN betyder att den gjorde en indexskanning. Om den inte hade använt indexet skulle den ha gjort en samlingsskanning (COLLSCAN ).

Det är samma sak när vi gör en fråga som involverar båda fälten i indexet:

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

Resultat:

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

Men om ett av fälten i frågan inte ingår i indexet resulterar det i en samlingsskanning:

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

Resultat:

{
	"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. Kan inte få Jedis-anslutning; Det gick inte att hämta en resurs från poolen

  2. MongoDB:upsert sub-dokument

  3. Begränsningar för Hadoop, sätt att lösa Hadoop-nackdelar

  4. MongoDB skapade filer