आपके द्वारा किए जाने वाले कार्यों की सही पहचान करके आप वहां के रास्ते का हिस्सा थे। लेकिन निश्चित रूप से $sort
$addToSetके लिए मान्य संशोधक नहीं है कोड>
चूंकि MongoDB मंत्र है "सेट को ऑर्डर नहीं किया जाता है" :
त्रुटि से संकेतित यहाँ दूसरी समस्या यह है कि आप एकाधिक अद्यतन ऑपरेटरों का उपयोग नहीं कर सकते (जैसे $addToSet
और $push
) एक ही समय में एक संपत्ति के लिए एक ही रास्ते पर। वास्तव में विभिन्न अद्यतन ऑपरेटरों के निष्पादन के लिए "कोई आदेश नहीं" है, इसलिए उनकी कोई गारंटी नहीं है कि $addToSet
$पुश
. से पहले होता है . वास्तव में वे समानांतर में काम कर रहे हैं, यही वजह है कि त्रुटि और इसकी अनुमति नहीं है।
पाठ्यक्रम का उत्तर "दो" अद्यतन कथन है। $addToSet
. के लिए एक और एक $sort
. लागू करने के लिए $each के माध्यम से एक खाली सरणी को "पुश" करके
,
लेकिन चूंकि हम वास्तव में प्रत्येक अपडेट को पूरा करने के लिए "प्रतीक्षा" नहीं करना चाहते हैं, इसलिए "बल्क" ऑपरेशन एपीआई यही है। तो आप सर्वर को दोनों निर्देश एक . में भेज सकते हैं भेजें और एक प्राप्त करें प्रतिक्रिया:
var bulk = db.perros.initializeOrderedBulkOp();
bulk.find({ "name": "Risas" }).update({
"$addToSet": {
"propiedades": { "name": "cola", "cantidad": 1 }
}
});
bulk.find({ "name": "Risas" }).update({
"$push": {
"propiedades": {
"$each": [ ], "$sort": { "cantidad": -1 }
}
}
});
bulk.execute();
तो यह वास्तव में अभी भी सर्वर के लिए केवल एक अनुरोध और एक प्रतिक्रिया है। यह अभी भी "दो" संचालन है, लेकिन ऊपरी और कुछ धागे के अद्यतन की अंतरिम स्थिति को हथियाने की संभावना नगण्य है।
इस दृष्टिकोण का एक विकल्प है जो "सेट डिटेक्शन" तर्क को .find()
में स्थानांतरित करना है। अपडेट स्टेटमेंट का हिस्सा और फिर बस $push
apply लागू करें जहां "सेट" में जोड़े जाने वाले सदस्य पहले से मौजूद नहीं हैं:
var bulk = db.perros.initializeOrderedBulkOp();
bulk.find({
"name": "Risas",
"propiedades": {
"$not": { "$elemMatch": { "name": "cola", "cantidad": 1 } }
}
}).update({
"$push": {
"propiedades": {
"$each": [{ "name": "cola", "cantidad": 1 }], "$sort": { "cantidad": -1 }
}
}
});
bulk.execute();
निश्चित रूप से जटिलता यह है कि यदि आप यहां "एकाधिक" सरणी तत्व जोड़ रहे हैं तो आपको उन $नहीं
और $elemMacth
एक $and
में परीक्षण
शर्त, और फिर यदि उन तत्वों में से "केवल एक" मान्य था तो इसे अकेले नहीं जोड़ा जा सकता था।
आप "एकाधिक" आइटम "पहले" के साथ उस तरह के ऑपरेशन को "कोशिश" कर सकते हैं, लेकिन फिर आपको चाहिए प्रत्येक के लिए "पुश" की संभावना को "परीक्षण" करने के लिए ऊपर के समान तर्क के साथ प्रत्येक व्यक्तिगत सरणी तत्व का "फ़ॉलबैक" निष्पादन है।
तो $addToSet
एकाधिक सरणी प्रविष्टियों के साथ उस दूसरे भाग को आसान बनाता है। एक प्रविष्टि के लिए बस "क्वेरी" और $पुश
. करना काफी आसान है , एक से अधिक के लिए $addToSet
के साथ "पहले" पैटर्न का उपयोग करने के लिए शायद यह छोटा रास्ता है और $पुश
दूसरे पैटर्न को लागू करने के बाद से परिणाम को "क्रमबद्ध" करने के लिए एक खाली सरणी का मतलब वैसे भी कई अद्यतन परीक्षण हैं।