wake-up-neo.net

Sortierung nach mehreren Feldern mongoDB

Ich habe eine Abfrage in Mongo, so dass ich dem ersten Feld und dann dem zweiten Feld den Vorzug geben möchte.

Angenommen, ich muss das so fragen

db.col.find({category: A}).sort({updated: -1, rating: -1}).limit(10).explain()

Also habe ich den folgenden Index erstellt

db.col.ensureIndex({category: 1, rating: -1, updated: -1})

Es wurden nur so viele Objekte gescannt, wie erforderlich, d. H. 10

Aber jetzt muss ich fragen 

db.col.find({category: { $ne: A}}).sort({updated: -1, rating: -1}).limit(10)

Also habe ich den folgenden Index erstellt

 db.col.ensureIndex({rating: -1, updated: -1})

dies führt jedoch zum Scannen des gesamten Dokuments und beim Erstellen 

 db.col.ensureIndex({ updated: -1 ,rating: -1})

Es scannt weniger Dokumente

Ich möchte nur darum bitten, sich über die Sortierung nach mehreren Feldern zu informieren und die Reihenfolge einzuhalten, die dabei erhalten bleibt. Durch das Lesen der Mongo-DB-Dokumente wird deutlich, dass das Feld, in dem die Sortierung durchgeführt werden muss, das letzte Feld sein sollte. Das ist also der Fall, von dem ich in meiner obigen $ ne Abfrage ausgegangen bin. Mache ich etwas falsch?

24
Global Warrior

Der MongoDB Abfrageoptimierer versucht, anhand verschiedener Pläne zu ermitteln, welcher Ansatz für eine gegebene Abfrage am besten geeignet ist. Der Gewinnerplan für dieses Abfragemuster wird dann für die nächsten ~ 1.000 Abfragen zwischengespeichert oder bis Sie eine explain() ausführen.

Um zu verstehen, welche Abfragepläne berücksichtigt wurden, sollten Sie explain(1) verwenden, zB:

db.col.find({category:'A'}).sort({updated: -1}).explain(1)

Im Detail allPlans werden alle verglichenen Pläne angezeigt.

Wenn Sie eine Abfrage ausführen, die nicht sehr selektiv ist (wenn beispielsweise viele Datensätze Ihren Kriterien von {category: { $ne:'A'}} entsprechen), ist es für MongoDB möglicherweise schneller, Ergebnisse mit einem BasicCursor (Tabellenscan) zu finden als mit einem Index abzugleichen.

Die Reihenfolge der Felder in query macht im Allgemeinen keinen Unterschied für die Indexauswahl (es gibt einige Ausnahmen bei Bereichsabfragen). Die Reihenfolge der Felder in sort beeinflusst die Indexauswahl. Wenn Ihre sort()-Kriterien nicht der Indexreihenfolge entsprechen, müssen die Ergebnisdaten nach der Verwendung des Index neu sortiert werden (in diesem Fall sollte scanAndOrder:true in der EXPLAIN-Ausgabe angezeigt werden).

Es ist auch erwähnenswert, dass MongoDB nur einen Index pro Abfrage verwendet (mit Ausnahme von $ors).

Wenn Sie also versuchen, die Abfrage zu optimieren:

db.col.find({category:'A'}).sort({updated: -1, rating: -1})

Sie möchten alle drei Felder in den Index aufnehmen:

db.col.ensureIndex({category: 1, updated: -1, rating: -1})

Zu Ihrer Information: Wenn Sie die Verwendung eines Index für eine bestimmte Abfrage erzwingen möchten (im Allgemeinen nicht erforderlich oder empfohlen), können Sie die Option hint() verwenden.

27
Stennie

Das stimmt, aber Sie haben hier zwei Sortierungsebenen, da Sie nach einem zusammengesetzten Index sortieren.

Wie Sie bemerkt haben, als das erste Feld des Index mit dem ersten Sortierfeld übereinstimmt, hat es funktioniert und der Index wurde gesehen. Bei der umgekehrten Arbeitsweise ist dies jedoch nicht der Fall.

Aufgrund Ihrer eigenen Beobachtungen muss die Reihenfolge der Felder vom ersten bis zum letzten Tag beibehalten werden. Der Mongo-Analysator kann sich manchmal um Felder bewegen, um einen Index abzugleichen. Normalerweise versucht er jedoch nur, das erste Feld abzugleichen, andernfalls wird es übersprungen.

1
Sammaye

probieren Sie diesen Code aus, um die Daten zuerst nach Namen zu sortieren und den 'Namen' im Schlüsselhalter zu belassen. Es wird 'Filter' sortiert. 

 var cursor = db.collection('vc').find({   "name" :   { $in: [ /cpu/, /memo/ ]   }     }, { _id: 0, }).sort( { "name":1  ,  "filter": 1 } );
0
Gajender Singh