जैसा कि उल्लेख किया गया है, $in क्लॉज की सरणी में तर्कों का क्रम दस्तावेज़ों को पुनर्प्राप्त करने के क्रम को प्रतिबिंबित नहीं करता है। यह निश्चित रूप से प्राकृतिक क्रम होगा या दिखाए गए अनुसार चयनित इंडेक्स ऑर्डर द्वारा होगा।
यदि आपको इस आदेश को संरक्षित करने की आवश्यकता है, तो आपके पास मूल रूप से दो विकल्प हैं।
तो मान लें कि आप _id
. के मानों पर मिलान कर रहे थे आपके दस्तावेज़ों में एक सरणी के साथ जो $in
. में पास होने वाली है जैसा [ 4, 2, 8 ]
।
एग्रीगेट का उपयोग करके दृष्टिकोण
var list = [ 4, 2, 8 ];
db.collection.aggregate([
// Match the selected documents by "_id"
{ "$match": {
"_id": { "$in": [ 4, 2, 8 ] },
},
// Project a "weight" to each document
{ "$project": {
"weight": { "$cond": [
{ "$eq": [ "$_id", 4 ] },
1,
{ "$cond": [
{ "$eq": [ "$_id", 2 ] },
2,
3
]}
]}
}},
// Sort the results
{ "$sort": { "weight": 1 } }
])
तो वह विस्तारित रूप होगा। यहां मूल रूप से क्या होता है कि जैसे मानों की सरणी $in
. को पास की जाती है आप एक "नेस्टेड" $cond
. भी बनाते हैं मूल्यों का परीक्षण करने और उचित भार निर्दिष्ट करने के लिए कथन। चूंकि वह "वजन" मान सरणी में तत्वों के क्रम को दर्शाता है, फिर आप अपने परिणामों को आवश्यक क्रम में प्राप्त करने के लिए उस मान को एक सॉर्ट चरण में पास कर सकते हैं।
बेशक आप वास्तव में कोड में पाइपलाइन स्टेटमेंट "बिल्ड" करते हैं, बहुत कुछ इस तरह:
var list = [ 4, 2, 8 ];
var stack = [];
for (var i = list.length - 1; i > 0; i--) {
var rec = {
"$cond": [
{ "$eq": [ "$_id", list[i-1] ] },
i
]
};
if ( stack.length == 0 ) {
rec["$cond"].push( i+1 );
} else {
var lval = stack.pop();
rec["$cond"].push( lval );
}
stack.push( rec );
}
var pipeline = [
{ "$match": { "_id": { "$in": list } }},
{ "$project": { "weight": stack[0] }},
{ "$sort": { "weight": 1 } }
];
db.collection.aggregate( pipeline );
mapReduce का उपयोग करके दृष्टिकोण करें
बेशक अगर यह सब आपकी संवेदनशीलता के लिए भारी लगता है तो आप वही काम कर सकते हैं mapReduce का उपयोग करना, जो आसान दिखता है लेकिन कुछ हद तक धीमा चल सकता है।
var list = [ 4, 2, 8 ];
db.collection.mapReduce(
function () {
var order = inputs.indexOf(this._id);
emit( order, { doc: this } );
},
function() {},
{
"out": { "inline": 1 },
"query": { "_id": { "$in": list } },
"scope": { "inputs": list } ,
"finalize": function (key, value) {
return value.doc;
}
}
)
और यह मूल रूप से उत्सर्जित "कुंजी" मानों पर निर्भर करता है कि वे "सूचकांक क्रम" में हैं कि वे इनपुट सरणी में कैसे होते हैं।
तो वे अनिवार्य रूप से एक इनपुट सूची के क्रम को $in
. पर बनाए रखने के आपके तरीके हैं ऐसी स्थिति जहां आपके पास पहले से ही एक निर्धारित क्रम में वह सूची है।