आप अपने मानदंड से मेल खाने वाले सरणी के कई तत्वों को किसी भी मूल .find()
. में वापस नहीं कर सकते हैं सवाल। एक से अधिक तत्वों का मिलान करने के लिए आपको .aggregate()
. का उपयोग करना होगा इसके बजाय विधि।
यहां मुख्य अंतर यह है कि "क्वेरी" वही करता है जो करने का इरादा है और आपकी शर्तों को पूरा करने वाले "दस्तावेजों" से मेल खाता है। आप स्थितीय $
. का उपयोग करने का प्रयास कर सकते हैं प्रोजेक्शन तर्क के भीतर ऑपरेटर, लेकिन नियम यह है कि यह केवल "पहले" सरणी तत्व से मेल खाएगा जो क्वेरी शर्तों से मेल खाता है।
एकाधिक सरणी तत्वों के लिए "फ़िल्टर" करने के लिए, निम्नानुसार आगे बढ़ें:
db.sample.aggregate([
// Filter possible documents
{ "$match": { "filtermetric.class": "s2" } },
// Unwind the array to denormalize
{ "$unwind": "$filtermetric" },
// Match specific array elements
{ "$match": { "filtermetric.class": "s2" } },
// Group back to array form
{ "$group": {
"_id": "$_id",
"filtermetric": { "$push": "$filtermetric" }
}}
])
MongoDB के आधुनिक संस्करणों में जो संस्करण 2.6 या उससे अधिक हैं, आप इसे $redact
के साथ कर सकते हैं :
db.sample.aggregate([
// Filter possible documents
{ "$match": { "filtermetric.class": "s2" } },
// Redact the entries that do not match
{ "$redact": {
"$cond": [
{ "$eq": [ { "$ifNull": [ "$class", "s2" ] }, "s2" ] },
"$$DESCEND",
"$$PRUNE"
]
}}
])
यह शायद आपका सबसे कुशल विकल्प है, लेकिन यह पुनरावर्ती है इसलिए पहले अपनी दस्तावेज़ संरचना पर विचार करें क्योंकि समान नामित फ़ील्ड किसी भी स्तर पर किसी अन्य शर्त के साथ मौजूद नहीं हो सकता है।
$map
के साथ यह तकनीक संभवत:सुरक्षित है लेकिन केवल तभी उपयोगी है जब सरणी में परिणाम "वास्तव में अद्वितीय" हों और $setDifference
:
db.sample.aggregate([
{ "$project": {
"filtermetric": { "$setDifference": [
{ "$map": [
"input": "$filtermetric",
"as": "el",
"in": {"$cond": [
{ "$eq": [ "$$el.class", "s2" ] },
"$$el",
false
]}
]},
[false]
]}
}}
])
यह भी ध्यान दें कि $group
. दोनों में और $project
परिचालन पाइपलाइन चरण आपको जरूरत उन सभी फ़ील्ड को निर्दिष्ट करने के लिए जिन्हें आप उस चरण से अपने परिणाम दस्तावेज़ों में वापस करना चाहते हैं।
अंतिम नोट यह है कि $elemMatch
जब आप किसी सरणी के भीतर केवल एक कुंजी के मान को क्वेरी कर रहे हों, तो इसकी आवश्यकता नहीं होती है। "डॉट नोटेशन" को प्राथमिकता दी जाती है और सरणी की केवल एक कुंजी तक पहुंचने पर अनुशंसा की जाती है। $elemMatch
केवल तभी आवश्यक होना चाहिए जब सरणी "तत्व" के भीतर दस्तावेज़ में "एकाधिक" कुंजियों को एक क्वेरी शर्त से मेल खाने की आवश्यकता हो।