2016-09-16 2 views
0

Ich habe einen ziemlich kleinen Datensatz von 63.000 Dokumenten (2,5 GB insgesamt). Beispiel für Dokument:

{ 
    _id : "[uniqueId]", 
    FormId : 10, 
    Name : "Name of form", 
    IsComplete : true, 
    Sections : [ many sections and can be large ] 
} 

Ich möchte die Gesamtzahl der Dokumente von FormId erhalten. Ich bekomme schnell Ergebnis (.15sec) auf dieser Abfrage:

db.getCollection('collection').aggregate([ 
    { $sort : { FormId : 1 } }, //Index exists on FormId 
    { $group : { _id : "$FormId", count : { $sum : 1 } } }, 
    { $sort : { "count" : -1 } } 
]) 

Mein Problem ist, ich brauche eine Zählung der Dokumente zu erhalten, wo { „IsComplete“: true}. Ich habe zwei Indizes, die auf beiden Eigenschaften basieren, aber ich stelle fest, dass mit dem Operator $ match alle Dokumente gescannt werden. Wie kann man die $ Gruppenanzahl effizient filtern?

+0

Sie brauchen hier nicht die erste '$ sort'-Stufe. – styvane

+0

@Styvane ohne die Gruppe $ sort stage $ dauert 10 Sekunden. Warum sollte das passieren? Beginnend mit $ sort uses index. – JayJohnsonDesigns

Antwort

0

effizienteste Weg würde

Filter nach unten, die Dokumente werden von $ Spiel mit nur passende Dokumente an die nächste Pipeline passieren. Indem Sie $ match ganz am Anfang einer Pipeline platzieren, kann die Abfrage Indizes nutzen.

Verwenden Sie $ project, um die Dokumente mit nur den erforderlichen Feldern an die nächste Stufe in der Pipeline weiterzuleiten. Dadurch werden die Daten für die nächste Pipeline weiter reduziert.

db.getCollection('collection').aggregate([ 
    { $match: {"IsComplete":true} }, 
    { $project: {"IsComplete":1, "FormId":1}}, 
    { $group : { _id : "$FormId", count : { $sum : 1 } } }, 
    { $sort : { "count" : -1 } } 
]) 
+0

Wenn ich zuerst $ match starte, dauert die Pipeline mehr als 10 Sekunden. Ich habe 2 separate Indizes für FormId und IsComplete. Warum sollte es so lange dauern? – JayJohnsonDesigns

+0

Da Index auf "IsComplete" nicht viele eindeutige Werte hat, ist die Indexierung eines Felds mit einer geringen Anzahl unterschiedlicher Werte nicht wirklich sinnvoll. Der andere Faktor ist, wie gut der Index Ihre Daten teilt, wenn Sie etwa die Hälfte Wahr und halb falsch, dann wird es helfen. – RootHacker

+0

Die Leistung hier hängt auch von dem Verhältnis der Werte von "IsComplete" und dem Wert gegen Sie die Abfrage zu treffen, wenn Sie Abfrage für wahr und Verhältnis von Daten ist 30:70 gegen wahr: falsch, dann kann es einige Zeit als es reduzieren wird nur mit kleinen Datensätzen umgehen. – RootHacker

Verwandte Themen