MongoDB
 sql >> Baza danych >  >> NoSQL >> MongoDB

Jak mogę $addToSet obiekt do tablicy i $sortować za pomocą MongoDB?

Byłeś częścią drogi, poprawnie identyfikując operacje, które musisz wykonać. Ale oczywiście $sort nie jest prawidłowym modyfikatorem dla $addToSet ponieważ mantra MongoDB brzmi "zestawy nie są uważane za zamówione" :

Innym problemem tutaj wskazanym przez błąd jest to, że nie można użyć wielu operatorów aktualizacji (takich jak $addToSet i $push ) na tej samej ścieżce do usługi w tym samym czasie. W rzeczywistości nie ma kolejności wykonywania różnych operatorów aktualizacji, więc nie ma gwarancji, że $addToSet występuje przed $push . W rzeczywistości prawdopodobnie działają równolegle, dlatego błąd jest niedozwolony.

Odpowiedzią są oczywiście „dwa” oświadczenia dotyczące aktualizacji. Jeden dla $addToSet i jeden do zastosowania $sort przez "wypychanie" pustej tablicy przez $each ,

Ale ponieważ naprawdę nie chcemy „czekać” na zakończenie każdej aktualizacji, do tego służy interfejs API operacji „Bulk”. Możesz więc wysłać obie instrukcje na serwer w jednym wyślij i odbierz jeden odpowiedź:

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();

Więc tak naprawdę jest to tylko jedno żądanie do serwera i jedna odpowiedź. To wciąż "dwie" operacje, ale narzut i możliwość przechwycenia przez jakiś wątek stanu przejściowego upadte są znikome.

Istnieje alternatywa dla tego podejścia, polegająca na przeniesieniu logiki „wykrywania zestawu” do .find() część instrukcji aktualizacji, a następnie po prostu zastosuj $push gdzie członkowie, którzy mają zostać dodani do „zestawu”, jeszcze nie istnieją:

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();

Oczywiście komplikacją jest to, że jeśli dodajesz „wiele” elementów tablicy, musisz owinąć te $nie i $elemMacth testy w $and warunek, a jeśli "tylko jeden" z tych elementów był poprawny, nie można go dodać samodzielnie.

Możesz „spróbować” tego rodzaju operację z „wieloma” elementami „najpierw”, ale potem powinno się wykonać "zastępcze" wykonanie każdego pojedynczego elementu tablicy z taką samą logiką jak powyżej, aby "przetestować" możliwość "wypychania" dla każdego z nich.

Więc $addToSet ułatwia tę drugą część dzięki wielu wpisom tablicy. Dla jednego wpisu wystarczy "zapytanie" i $push , dla więcej niż jednego jest to prawdopodobnie krótsza ścieżka do użycia "pierwszego" wzorca z $addToSet i $push pusta tablica do "sortowania" wyniku, ponieważ zastosowanie drugiego wzorca i tak oznacza wielokrotne testy aktualizacji.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Zapytanie MongoDB dla wszystkich dokumentów z unikalnym polem

  2. Uruchamianie zreplikowanej bazy danych MongoDB 4.2 w Kubernetes:konfiguracja replset nie jest odbierana

  3. Wpychaj przedmioty do tablicy mongo za pomocą mongoose

  4. Projekt z dopasowaniem łącznie nie działa w mongodb

  5. Mangusta lub zapytanie