MongoDB में, जब आप किसी सरणी वाले फ़ील्ड पर एक अनुक्रमणिका बनाते हैं, तो यह स्वचालित रूप से एक बहु-कुंजी अनुक्रमणिका के रूप में बन जाती है।
बहु-कुंजी अनुक्रमणिका सरणी फ़ील्ड के विरुद्ध कुशल क्वेरी का समर्थन करती हैं।
स्केलर डेटा (जैसे स्ट्रिंग्स, नंबर, आदि) और नेस्टेड दस्तावेज़ रखने वाली सरणियों के लिए मल्टीकी इंडेक्स बनाए जा सकते हैं।
उदाहरण
मान लीजिए हमारे पास products . नामक संग्रह है जिसमें निम्नलिखित दस्तावेज शामिल हैं:
{ "_id" : 1, "product" : "Bat", "sizes" : [ "S", "M", "L" ] }
{ "_id" : 2, "product" : "Hat", "sizes" : [ "S", "L", "XL" ] }
{ "_id" : 3, "product" : "Cap", "sizes" : [ "M", "L" ] } हम उस संग्रह पर इस तरह एक बहु-कुंजी अनुक्रमणिका बना सकते हैं:
db.products.createIndex(
{
"sizes": 1
}
) यह एक नियमित इंडेक्स बनाने जैसा है। आपको स्पष्ट रूप से यह निर्दिष्ट करने की आवश्यकता नहीं है कि यह एक बहु-कुंजी अनुक्रमणिका है। MongoDB यह निर्धारित करने में सक्षम है कि फ़ील्ड में एक सरणी है, और इसलिए इसे एक बहु-कुंजी अनुक्रमणिका के रूप में बनाएं।
बहु-कुंजी अनुक्रमणिका के साथ, MongoDB सरणी में प्रत्येक तत्व के लिए एक अनुक्रमणिका कुंजी बनाता है।
एम्बेडेड दस्तावेज़ों पर मिश्रित बहुकुंजी अनुक्रमणिका
जैसा कि उल्लेख किया गया है, आप एम्बेडेड दस्तावेज़ रखने वाले सरणियों के लिए बहु-कुंजी अनुक्रमणिका बना सकते हैं।
आप इन पर एक मिश्रित अनुक्रमणिका बना सकते हैं, ताकि आपकी अनुक्रमणिका सरणी में एकाधिक फ़ील्ड के विरुद्ध बनाई जा सके।
मान लीजिए हमारे पास restaurants . नामक संग्रह है इस तरह के दस्तावेज़ों के साथ:
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
}]
}
]) हम इस तरह एक मिश्रित बहुकुंजी अनुक्रमणिका बना सकते हैं:
db.restaurants.createIndex(
{
"reviews.ordered": 1,
"reviews.rating": -1
}
) अब, जब भी हम उन क्षेत्रों को शामिल करने वाली क्वेरी चलाते हैं, तो बहु-कुंजी अनुक्रमणिका का उपयोग किया जाएगा।
जब हम इनमें से किसी एक फ़ील्ड में खोज करते हैं तो क्वेरी योजना कैसी दिखती है:
db.restaurants.find( { "reviews.ordered": "Dinner" } ).explain() परिणाम:
{
"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
}
वह भाग जो IXSCAN . पढ़ता है इसका मतलब है कि उसने एक इंडेक्स स्कैन किया था। यदि उसने अनुक्रमणिका का उपयोग नहीं किया होता, तो वह एक संग्रह स्कैन (COLLSCAN) कर लेता। )।
यह वही होता है जब हम एक क्वेरी करते हैं जिसमें इंडेक्स में दोनों फ़ील्ड शामिल होते हैं:
db.restaurants.find( { "reviews.ordered": "Dinner", "reviews.rating": { $gt: 3 } } ).explain() परिणाम:
{
"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
} हालांकि, यदि क्वेरी में से कोई एक फ़ील्ड अनुक्रमणिका में शामिल नहीं है, तो इसका परिणाम संग्रह स्कैन में होता है:
db.restaurants.find( { "reviews.name": "Lisa", "reviews.rating": { $gt: 3 } } ).explain() परिणाम:
{
"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
}