2016-07-10 11 views
0

ich ein hypothetisches Modell habe unten, mit Knoten-mongodb-native-LaufwerkMongoDB Aktualisierung Eltern & Eltern Eltern & so fro

A01 hat ein direktes Kind (A03), ein Enkelkind (A04) und einen Urenkel (A05): A01 -> A03 -> A04 -> A05

A02 hat ein direktes Kind (A06)

Wenn ein Kind eine Punktzahl bekommen, alle Eltern bekommt es. Zum Beispiel, wenn ich eine Partitur A05 geben, alle Eltern (A01 bis A04) einen Punktzahl

[{ 
    _id: 'A01', 
    p_id: '', // parent _id 
    score: 0, 
}, { 
    _id: 'A02', 
    p_id: '', 
    score: 0, 
}, { 
    _id: 'A03', 
    p_id: 'A01', 
    score: 0, 
}, { 
    _id: 'A04', 
    p_id: 'A03', 
    score: 0, 
}, { 
    _id: 'A05', 
    p_id: 'A04', 
    score: 0, 
}, { 
    _id: 'A06', 
    p_id: '', 
    score: 0, 
}, 
{ 
    _id: 'A07', 
    p_id: 'A02', 
    score: 0, 
}, { 
    _id: 'A08', 
    p_id: '', 
    score: 0, 
}] 


// my naive implementation 
function updateScore({ _id, score }) { 
    return db.collection 
    .findOneAndUpdate({ _id: }, { $inc: { score } }) 
    .then(function ({ value }) { 
     if (value && value.p_id) return updateScore({ _id: value.p_id, score }) // recursively update the parent score 
     return Promise.resolve() // if no parent is found 
    }) 
    .catch(function (error) {}) 
} 

updateScore({ _id: 'A05', score: 1 }) 

In meiner naiven Funktion erhalten, die Anwendung eine Abfrage senden (die Partitur von A05 von 1 zu erhöhen) zum Mongo-Server. Der Mongo-Server empfängt die Abfrage und führt sie aus, gibt die Daten an die Anwendung zurück. Die Anwendung überprüft, ob es eine übergeordnete _id gibt, und sendet die Abfrage dann an den mongo-Server. Der Prozess wird wiederholt, bis keine übergeordnete _id mehr vorhanden ist.

Mein Gedanke ist, dass das Senden von Daten zwischen der Anwendung und dem Mongo-Server nicht die beste Option ist, (1) Latenz, wenn der Mongo-Server remote gehostet wird, (2) Bandbreite zu verbrauchen, wenn die Daten riesig sind.

ich bulkWrite sah, aber es kann nicht aktualisiert werden, wenn es nicht die p_id

ich running js file in mongo shell sah weiß, das anzeigt „Verbindung ist schnell mit geringer Latenz“ und Store a JavaScript Function on the Server aber es sagt „Lagern Sie keine Logik Anwendung in der Datenbank. " und möglicherweise nicht so "schnell".

Also die Frage: Was ist der "beste" Weg in dieser Situation, Aktualisierung der Punktzahl für alle Eltern.

Antwort

1

Ich würde ...

  • eine Graph-Datenbank verwendet stattdessen, dass diese Art von Updates nativ ermöglicht.
  • Hinzufügen eines anderen Felds wie "family_id", so dass Sie ein einzelnes Multi-Update durchführen können: db.collection.update({"family_id": "123"}, { $inc: { score } }).
  • Ähnlich wie oben, Speichern einer Liste der Eltern für jedes Kind. Dies könnte Sie auf zwei Updates bringen (suchen und update Kind; Aktualisieren Sie alle Eltern).

In jedem Fall könnten Sie auch nicht der Eltern Partituren Aktualisierung betrachten, sondern ihre Kinder Summieren, wenn Sie die Punktzahl berechnen müssen. Bei einigen Schemaänderungen können Sie dafür die Aggregationspipeline verwenden. Dies wäre effizienter, wenn Sie häufig erhöhen und selten abfragen.