MongoDB
 sql >> база данни >  >> NoSQL >> MongoDB

Как мога да $addToSet обект към масив и $sort също с помощта на MongoDB?

Вие бяхте част от пътя дотам, като правилно идентифицирахте операциите, които трябва да извършите. Но разбира се $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 празен масив за „сортиране“ на резултата, тъй като прилагането на втория модел така или иначе означава множество тестове за актуализиране.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Как мога да използвам туитове от API за стрийминг на Twitter и да ги съхранявам в mongodb

  2. MongoDB $setEquals

  3. MongoDB $currentDate

  4. инсталирането на mongodb-10gen е неуспешно с apt-get

  5. Четете данни от MongoDB (gridfs) чрез Matlab и Java драйвер