वास्तव में इसका सबसे पहले उत्तर देने के लिए, आपको दी गई शर्त के लिए मैचों की संख्या की "गणना" करने की आवश्यकता है ताकि परिणामों को "क्रमबद्ध" किया जा सके और शीर्ष पर सबसे अधिक मैचों को वरीयता दी जा सके।
इसके लिए आपको एकत्रीकरण ढांचे की आवश्यकता है, जिसका उपयोग आप MongoDB में डेटा की "गणना" और "हेरफेर" के लिए करते हैं:
db.multiArr.aggregate([
{ "$match": { "Keys": { "$in": [ "carrot", "banana" ] } } },
{ "$project": {
"ID": 1,
"Keys": 1,
"order": {
"$size": {
"$setIntersection": [ ["carrot", "banana"], "$Keys" ]
}
}
}},
{ "$sort": { "order": -1 } }
])
संस्करण 3 से पुराने मोंगोडीबी पर, आप लंबा फॉर्म कर सकते हैं:
db.multiArr.aggregate([
{ "$match": { "Keys": { "$in": [ "carrot", "banana" ] } } },
{ "$unwind": "$Keys" },
{ "$group": {
"_id": "$_id",
"ID": { "$first": "$ID" },
"Keys": { "$push": "$Keys" },
"order": {
"$sum": {
{ "$cond": [
{ "$or": [
{ "$eq": [ "$Keys", "carrot" ] },
{ "$eq": [ "$Keys", "banana" ] }
]},
1,
0
]}
}
}
}},
{ "$sort": { "order": -1 } }
])
किसी भी मामले में यहां फ़ंक्शन $in
के साथ तर्कों की "सूची" प्रदान करके पहले संभावित दस्तावेज़ों को शर्तों से मिलाना है . एक बार परिणाम प्राप्त हो जाने के बाद आप प्रदान किए गए संभावित मानों की "सूची" में सरणी में मिलान करने वाले तत्वों की संख्या "गिनती" करना चाहते हैं।
आधुनिक रूप में $setIntersection
ऑपरेटर दो "सूचियों" की तुलना एक नई सरणी लौटाता है जिसमें केवल "अद्वितीय" मिलान करने वाले सदस्य होते हैं। चूंकि हम जानना चाहते हैं कि कितने मैच थे, हम केवल $size
. लौटाते हैं उस सूची का।
पुराने संस्करणों में, आप $unwind
. के साथ दस्तावेज़ सरणी को अलग करते हैं इस पर संचालन करने के लिए क्योंकि पुराने संस्करणों में नए ऑपरेटरों की कमी थी जो बिना बदलाव के सरणियों के साथ काम करते थे। प्रक्रिया तब प्रत्येक मान को अलग-अलग देखती है और यदि या तो अभिव्यक्ति $or
. में है संभावित मानों से मेल खाता है तो $cond
टर्नरी 1
. का मान देता है $sum
. तक संचायक, अन्यथा 0
. शुद्ध परिणाम वही "मैचों की गिनती" है जैसा कि आधुनिक संस्करण के लिए दिखाया गया है।
अंतिम बात बस $sort
. करना है "मैचों की गिनती" के आधार पर परिणाम जो लौटाए गए थे, इसलिए अधिकांश मैच "शीर्ष" पर हैं। यह "अवरोही क्रम" है और इसलिए आप -1
. की आपूर्ति करते हैं यह इंगित करने के लिए।
$in और सरणियों से संबंधित परिशिष्ट
आप शुरुआत के लिए MongoDB प्रश्नों के बारे में कुछ बातों को गलत समझ रहे हैं। $in
ऑपरेटर वास्तव में इस तरह के तर्कों की "सूची" के लिए अभिप्रेत है:
{ "Keys": { "$in": [ "carrot", "banana" ] } }
जो अनिवार्य रूप से कहने का संक्षिप्त तरीका है "या तो 'गाजर' का मिलान करें या संपत्ति 'कुंजी' में 'केला'" . और इस तरह लंबे रूप में भी लिखा जा सकता है:
{ "$or": [{ "Keys": "carrot" }, { "Keys": "banana" }] }
जो वास्तव में आपको ले जाना चाहिए यदि यह "एकवचन" मैच की स्थिति थी, तो आप बस संपत्ति से मिलान करने के लिए मूल्य की आपूर्ति करते हैं:
{ "Keys": "carrot" }
तो यह उस गलत धारणा को कवर करना चाहिए जिसका आप उपयोग करते हैं $in
एक संपत्ति से मेल खाने के लिए जो एक दस्तावेज़ के भीतर एक सरणी है। इसके बजाय "रिवर्स" केस इच्छित उपयोग है जहां इसके बजाय आप किसी दिए गए संपत्ति से मेल खाने के लिए "तर्कों की सूची" की आपूर्ति करते हैं, वह संपत्ति एक सरणी या केवल एक मान हो।
MongoDB क्वेरी इंजन समानता या समान ऑपरेशन में एकल मान या मानों की सरणी के बीच कोई अंतर नहीं करता है।