MongoDB, bedingte upserts oder updates
Bei der Verwendung von MongoDB ich bin derzeit dabei einen bedingten upsert als Teil einer aggregation-Prozess auf die form (vereinfachte alot):
db.dbname.update({attr1 : value1, attr2 : value2},
{"$inc" : { avg : current_value, nr : 1}},
false (multi), true (upsert))
Aber ich möchte in der Lage, eine maximale (und minimal -) Wert als auch, ohne zum abrufen des Dokuments. Etwas entlang der Linien von:
db.dbname.update({ attr1 : value1, attr2 : value2},
{"$inc" : { avg : current_value, nr : 1},
"$setIfBigger" : { max : current_value}},
false (multi), true (upsert))
Ist das möglich in einer effizienten Weise?
Meine aktuelle, äußerst ineffizient, Lösung ist, dass ich prüfen, ob eine aktuelle aggregation Dokument, und wenn es vorhanden ist, aktualisiere ich die Werte entsprechend an, und wenn nicht ich ein neues Dokument erstellen. Beispiel (wieder vereinfacht eine Menge, aber die Essenz ist da):
var obj = db.dbname.findOne({attr1 : value1, attr2 : value2},{_id:1});
if (obj != null) {
db.dbname.update({attr1 : value1, attr2 : value2},
{"$inc" : { avg : current_value, nr : 1},
"$set" : { max : (obj.max > current_value ? obj.max : current_value}},
false (multi), true (upsert));
} else {
db.dbname.save({attr1 : value1, attr2 : value2,
avg : current_value, nr : 1,
max : current_value});
}
Das eigentliche Programm ist in Java geschrieben und verwendet die mongo-API, und die aggregation Prozess ist sehr Komplex und verwendet Kompositionstechniken Weg über Javascript für die Kommunikation mit anderen Servern, ergo mapreduce ist keine option. Schließlich das Endergebnis ist durchaus ein gigantischer einfache Werte, die ich speichern möchten, in der möglichst effiziente Weise und auch zur Speicherung von vorberechneten Mittelwerte, Maxima und minima bestimmter Kombinationen.
Einer Lösung ist die Erstellung von einzigartigen Funktion-Objekte in JS für jedes einzelne update, was ich glaube, ist nicht eine effiziente Möglichkeit?
Das Hauptziel ist die Verringerung der Zeitdauer für die Durchführung einer aggregation dieser Art, die Bandbreite ist zweitrangig.
InformationsquelleAutor flindeberg | 2011-04-04
Du musst angemeldet sein, um einen Kommentar abzugeben.
Diese können nun viel leichter in die MongoDB 2.6-Version, die beinhaltet Insert-und Update-Verbesserungen. Insbesondere gibt es neue $min und $max, dass die Betreiber führen ein bedingtes update, je nach der relativen Größe von dem angegebenen Wert und dem aktuellen Wert eines Feldes.
So zum Beispiel das update:
wäre bedingt update des angegebenen Dokuments, wenn 950 ist größer als der aktuelle Wert von
highScore
.InformationsquelleAutor helmy
Kann nicht so funktionieren wie Sie es gerne hätten:
https://jira.mongodb.org/browse/SERVER-458
Das Problem, das Sie gegenüberstellen, ist, dass Sie wollen, MongoDB zum durchführen einer upsert mit etwas komplexeren Logik. Sie wollen also die Nutzung der Dokument-Ebene sperren, um effektiv zu "trigger" mehrere komplexe änderungen auf einmal.
Du bist nicht der erste, der das zu wollen, leider ist es nicht verfügbar. Es gibt verschiedene server-Fehler verbunden mit dieser Art von "komplexer update-Verhalten". Sie Mai wollen Uhr /Abstimmung über ein paar von den folgenden zu prüfen, für den Fortschritt.
$Satz
nur beim einsetzen, fügen Sie nur, wenn keine bestehende,push
undset
zur gleichen Zeit, koordinieren, eine "Größe" mit$addToSet
.Insbesondere SERVER-458 scheint am nächsten zu dem, was Sie wollen.
Sie können auf jeden Fall einen Antrag auf diese Optionen (jira.mongodb.org).
Geändert die richtige Antwort, da
MongoDB
hat jetzt bekommen die benötigte Funktionalität. Ich bin ein bisschen unsicher, ob dies korrekt ist oder nicht, wird mit Bezug auf die Ethik SO..es ist 15 Punkte, ich habe 25k+ und über 600 Antworten, so werde ich Leben 🙂 Und hey, es sieht aus wie eine der 4 Fragen wurde eigentlich behoben, die in den letzten 3+ yeaars. Yay Mongo!
InformationsquelleAutor Gates VP