Вие бяхте част от пътя дотам, като правилно идентифицирахте операциите, които трябва да извършите. Но разбира се $sort
не е валиден модификатор за $addToSetкод>
тъй като мантрата на MongoDB е "наборите не се считат за подредени" :
Другият проблем тук, както е посочено от грешката, е, че не можете да използвате множество оператори за актуализиране (като $addToSet
и $push
) по същия път към свойство едновременно. Всъщност "няма ред" за изпълнението на различни оператори за актуализиране, така че не е гаранция, че $addToSet
възниква преди $push
. Всъщност те вероятно действат паралелно, което е причината за грешката и че това не е позволено.
Отговорът разбира се е "две" изявления за актуализиране. Един за $addToSet
и един за прилагане на $sort
чрез „натискане“ на празен масив чрез $each
,
Но тъй като наистина не искаме да „чакаме“ всяка актуализация да завърши, това е, за което служи API за групови операции. Така че можете да изпратите и двете инструкции към сървъра в едно изпратете и вземетеедин отговор:
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();
Така че това наистина е само една заявка към сървъра и един отговор. Това все още са "две" операции, но режийните разходи и възможността някоя нишка да грабне междинното състояние на upadte са незначителни.
Има алтернатива на този подход, която е да преместите логиката на „set detection“ в .find()
част от израза за актуализиране и след това просто приложете $push
където членът(ите), които ще бъдат добавени към „набора“, вече не съществуват:
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();
Разбира се, усложнението е, че ако добавяте "множество" елементи от масив тук, ще трябва да обвиете тези $not
и $elemMacth
тестове в $and
условие и след това, ако „само един“ от тези елементи е валиден, тогава той не може да бъде добавен сам.
Можете да „опитате“ този вид операция с „множество“ елементи „първо“, но след това трябва има "резервно" изпълнение на всеки отделен елемент от масива със същата логика като по-горе, за да "тества" възможността за "натискане" за всеки един.
Така че $addToSet
прави тази втора част лесна с множество записи в масив. За един запис е доста лесно просто да "заявите" и $push
, за повече от един вероятно е по-краткият път да използвате "първия" модел с $addToSet
и $push
празен масив за „сортиране“ на резултата, тъй като прилагането на втория модел така или иначе означава множество тестове за актуализиране.