2016-07-05 5 views
15

Ich bin mit MongoDB, und ich habe eine Sammlung von Dokumenten mit folgenden Struktur:Index Bounds auf Mongo Regex Suchen

{ 
    fName:"Foo", 
    lName:"Barius", 
    email:"[email protected]", 
    search:"foo barius" 
} 

Ich baue eine Funktion, die ein regulären Ausdruck sucht auf das search Feld durchführen wird . Um die Leistung zu optimieren, habe ich diese Sammlung im Suchfeld indiziert. Die Dinge sind jedoch immer noch ein bisschen langsam. Also lief ich eine explain() auf einer Beispielabfrage:

db.Collection.find({search:/bar/}).explain(); 

unter dem Gewinnplan Sehen, sehe ich die folgenden Indexgrenzen verwendet:

"search": [ 
     "[\"\", {})", 
     "[/.*bar.*/, /.*bar.*/]" 
] 

Der zweite Satz macht Sinn - es ist von allem suchen, enthält bar zu allem, was bar enthält. Der erste Satz verblüfft mich jedoch. Es scheint in den Grenzen von "" einschließlich {} exklusiv zu suchen. Ich bin besorgt, dass dieser zusätzliche Satz von Grenzen meine Abfrage verlangsamt. Ist es notwendig zu halten? Wenn nicht, wie kann ich verhindern, dass es einbezogen wird?

+0

Hat das gleiche Problem, hast du eine Erklärung gefunden? – kirhgoff

+0

@kirhgoff Welche Version von mongoDB benutzt du? – barbakini

+0

10 @kirhgoff was benutzt du 'mongoDB native' oder' mongoose'. Sieh dir das an - http://voidcanvas.com/mongoose-vs-mongodb-native/ –

Antwort

5

Ich denke, es ist nur die Art, wie mongodb mit Regex funktioniert (siehe https://scalegrid.io/blog/mongodb-regular-expressions-indexes-performance/). Achten Sie nur auf den Wert von nscanned/totalKeysExamined. Wenn der Wert zu groß ist, ist der Index für Ihre Abfrage nutzlos.

Siehe auch: MongoDB, performance of query by regular expression on indexed fields

+0

Zustimmen, wie in der MongoDB-Dokumentation und in https://stackoverflow.com/a/33219393 angegeben/8291949 Wenn Ihre Regex kein "Präfix-Ausdruck" ist, wird mongo die Schlüssel im Index vollständig scannen und dann die übereinstimmenden Dokumente abrufen (was immer noch schneller als ein vollständiger Sammlungs-Scan sein sollte). – wp78de

0

Dies ist die Art und Weise Mongo mit dieser Art von Regex und einem Index funktioniert. Was ich meine ist, dass Sie nach/bar/statt/^ bar/suchen.

Wenn Sie einen Index für dieses Feld angeben, wird vom ersten Zeichen aus indexiert. So wird "Foo barius" beginnend mit F indiziert. Da Sie irgendwo im Feld nach "bar" suchen, müssen Sie den gesamten Index auf diesem Feld mit * bar * suchen.

Die erste Zeile in Ihrer Erklärung sagt, dass jeder Datensatz im Index betrachtet wird.

Die zweite Zeile sagen, geben Sie mir nur die Indizes von (1), die bar in ihnen haben.

Fazit: Entwerfen Sie Ihre Datensätze so, dass sie den Index effizient nutzen. Stellen Sie bei Zeichenfolgen sicher, dass sich Ihre Suchen am Anfang der Zeichenfolge befinden, z. B./^ bar /. Wenn ich nach Nachnamen suche, muss es zuerst in einem indizierten Feld vorkommen.

Als Übung machen Sie eine Erklärung auf/^ bar/stattdessen. Sie werden Ihre Daten nicht erhalten, aber die ersten Indexgrenzen sind etwas wie/^ bar/to/^ bas /.

Ich hoffe, mein Strom des Bewusstseins Antwort ist hilfreich.

UDude

-1

Ich dachte, ich würde meine zwei Cent hinzufügen.

Die vorherigen zwei Antworten sind korrekt. Der Regex-Ausdruck kann nur dann einen Standardindex verwenden, wenn Sie Ihre Suche von Anfang an starten. Tatsächlich kann sich ein Index und die Suche nach Regex nachteilig auf Ihre Suche auswirken, da er versucht, den Index zu verwenden, aber nicht erfolgreich ist.

Es gibt eine andere Art von Index, die in Ihrer Situation nützlich sein kann. Mongo's Textindex.Es Indizes jedes Wort auf die Felder basiert, so dass es der Lage wäre, eine indizierte Suche auf beiden Wörter „foo“ und „Barius“ zu tun, die mehr

Hier ist die Dokumentation für das verwenden könnte: https://docs.mongodb.com/manual/core/index-text/