2016-11-03 4 views
1

Wir Version die meisten unserer Sammlungen in Mongodb. Der gewählte Versionierung Mechanismus ist wie folgt:MongoDB Aggregation Abfrage läuft sehr langsam

{ "docId" : 174, "v" : 1, "attr1": 165 } /*version 1 */ 
{ "docId" : 174, "v" : 2, "attr1": 165, "attr2": "A-1" } 
{ "docId" : 174, "v" : 3, "attr1": 184, "attr2" : "A-1" } 

Also, wenn wir unsere Anfragen führen wir immer verwenden müssen, um auf diese Weise die Aggregation Rahmen, um sicherzustellen neuesten Versionen unserer Objekte zu erhalten:

db.docs.aggregate([ 
    {"$sort":{"docId":-1,"v":-1}}, 
    {"$group":{"_id":"$docId","doc":{"$first":"$$ROOT"}}} 
    {"$match":{<query>}} 
]); 

Die Problem mit diesem Ansatz ist, sobald Sie Ihre Gruppierung getan haben, haben Sie eine Reihe von Daten im Speicher, die nichts mit Ihrer Sammlung zu tun hat und somit Ihre Indizes nicht verwendet werden können.

Je mehr Dokumente Ihre Sammlung hat, desto langsamer wird die Abfrage.

Gibt es eine Möglichkeit, dies zu beschleunigen?

Wenn nicht, werde ich prüfen, zu einem der Ansätze in diesem guten Beitrag definiert zu bewegen: http://www.askasya.com/post/trackversions/

+0

Warum haben Sie nicht $ Match in der ersten Stufe? –

+0

Fügen Sie dem Feld "docId" Ihres Dokuments einen Index hinzu. –

+0

@DanieleTassone Ich fürchte, das ist keine Option. Erklärung ist in Verbindung, die ich zur Verfügung stellte. Grundsätzlich, wenn Sie am Anfang filtern, werden Sie mit Versionen enden, die nicht die neuesten sind, aber die Sortiergruppenphase wird sie als solche betrachten. Es ist ein häufiger Fehler, wenn eine solche Versionierung durchgeführt wird. – jbernal

Antwort

0

Genau um diese Frage zu vervollständigen, gingen wir mit der Option 3: eine Sammlung neueste Versionen zu halten und einem Sammlung, um historische zu halten. Es ist hier eingeführt: http://www.askasya.com/post/trackversions/ und einige weitere Beschreibung (mit einigen netten Code-Schnipsel) kann in http://www.askasya.com/post/revisitversions/ gefunden werden.

Es läuft seit 6 Monaten in der Produktion. So weit, ist es gut. Früherer Ansatz bedeutete, dass wir immer das Aggregat-Framework verwendeten, das sich von Indizes wegbewegt, sobald Sie das ursprüngliche Schema ändern (mit $ group, $ project ...), da es nicht mehr mit der ursprünglichen Sammlung übereinstimmt. Dies machte unsere Leistung fürchterlich, während die Daten zunahmen.

Mit dem neuen Ansatz ist das Problem jedoch verschwunden. 90% unserer Anfragen gehen gegen die neuesten Daten vor und das bedeutet, dass wir eine Sammlung mit einem einfachen ObjectId als Bezeichner anvisieren, und wir benötigen kein aggregiertes Framework mehr, sondern nur reguläre Funde.

Unsere Abfragen für historische Daten sind stets bemüht, id und version so durch diese Indizierung (wir sind beide als _id, so dass wir es aus dem Kasten heraus zu bekommen), liest auf diese Sammlungen gleich schnell sind. Dies ist ein Punkt, aber nicht zu übersehen. Lesemuster in Ihrer Anwendung sind entscheidend, wenn Sie entwerfen, wie Ihre Collections/Schemas in MongoDB aussehen sollen. Daher müssen Sie sicherstellen, dass Sie diese bei solchen Entscheidungen kennen.