Beispiel:
> db.stuff.save({"foo":"bar"});
> db.stuff.find({"foo":"bar"}).count();
1
> db.stuff.find({"foo":"BAR"}).count();
0
mongodb
case-insensitive
Luke Dennis
quelle
quelle
$caseSensitive: false
. Siehe: docs.mongodb.org/manual/reference/operator/query/text/…$caseSensitive
ist bereits standardmäßig false, und das beantwortet die Frage nicht, da es nur für indizierte Felder funktioniert. OP suchte nach einem String-Vergleich ohne Berücksichtigung der Groß- und Kleinschreibung.Antworten:
Sie könnten einen regulären Ausdruck verwenden .
In Ihrem Beispiel wäre das:
Ich muss jedoch sagen, dass Sie den Wert auf dem Weg dorthin möglicherweise nur in Kleinbuchstaben (oder Großbuchstaben) umwandeln können, anstatt jedes Mal, wenn Sie ihn finden, die zusätzlichen Kosten zu verursachen. Offensichtlich funktioniert dies nicht für die Namen von Personen und dergleichen, aber möglicherweise für Anwendungsfälle wie Tags.
quelle
AKTUALISIEREN:
Die ursprüngliche Antwort ist jetzt veraltet. Mongodb unterstützt jetzt die erweiterte Volltextsuche mit vielen Funktionen.
URSPRÜNGLICHE ANTWORT:
Es sollte beachtet werden, dass das Suchen mit der Groß- und Kleinschreibung von Regex / i bedeutet, dass Mongodb nicht nach Index suchen kann, sodass Abfragen für große Datenmengen lange dauern können.
Selbst mit kleinen Datensätzen ist es nicht sehr effizient. Sie erzielen einen weitaus größeren CPU-Treffer als Ihre Abfragebefehle, was zu einem Problem werden kann, wenn Sie versuchen, eine Skalierung zu erreichen.
Alternativ können Sie eine Kopie in Großbuchstaben speichern und danach suchen. Zum Beispiel habe ich eine Benutzertabelle mit einem Benutzernamen, der in Groß- und Kleinschreibung geschrieben ist, aber die ID ist eine Kopie des Benutzernamens in Großbuchstaben. Dies stellt sicher, dass eine Duplizierung ohne Berücksichtigung der Groß- und Kleinschreibung nicht möglich ist (sowohl "Foo" als auch "foo" sind nicht zulässig), und ich kann nach id = username.toUpperCase () suchen, um eine Suche nach Benutzernamen ohne Berücksichtigung der Groß- und Kleinschreibung zu erhalten.
Wenn Ihr Feld groß ist, z. B. ein Nachrichtentext, ist das Duplizieren von Daten wahrscheinlich keine gute Option. Ich glaube, dass die Verwendung eines externen Indexers wie Apache Lucene in diesem Fall die beste Option ist.
quelle
username: 'bill'
passendenBILL
oderBill
nicht eine Volltextsuchabfrage, die auch Spiel würde Worte stammte vonbill
, wieBills
,billed
usw.Wenn Sie den regulären Ausdruck aus einer Variablen erstellen müssen, ist dies eine viel bessere Möglichkeit: https://stackoverflow.com/a/10728069/309514
Sie können dann so etwas tun wie:
Dies hat den Vorteil, dass es programmatischer ist oder Sie eine Leistungssteigerung erzielen können, indem Sie es im Voraus kompilieren, wenn Sie es häufig wiederverwenden.
quelle
new RegExp("^" + req.params.term.toLowerCase(), "i")
funktioniert auch gutBeachten Sie, dass das vorherige Beispiel:
Wenn alle Einträge, die bar enthalten , mit der Abfrage übereinstimmen (bar1, barxyz, openbar), kann dies für eine Suche nach Benutzernamen in einer Authentifizierungsfunktion sehr gefährlich sein ...
Möglicherweise müssen Sie festlegen, dass es nur mit dem Suchbegriff übereinstimmt, indem Sie die entsprechende Regexp-Syntax wie folgt verwenden:
Unter http://www.regular-expressions.info/ finden Sie Syntaxhilfen für reguläre Ausdrücke
quelle
Ab MongoDB 3.4 wird empfohlen, einen schnellen Index ohne Berücksichtigung der Groß- und Kleinschreibung zu verwenden, um eine schnelle Suche ohne Berücksichtigung der Groß- und Kleinschreibung durchzuführen .
Ich habe persönlich einen der Gründer per E-Mail benachrichtigt, damit dies funktioniert, und er hat es möglich gemacht! Es war seit 2009 ein Problem bei JIRA , und viele haben die Funktion angefordert. So funktioniert das:
Ein Index ohne Berücksichtigung der Groß- und Kleinschreibung wird erstellt, indem eine Kollatierung mit einer Stärke von 1 oder 2 angegeben wird. Sie können einen Index ohne Berücksichtigung der Groß- und Kleinschreibung wie folgt erstellen:
Sie können beim Erstellen auch eine Standardkollatierung pro Sammlung angeben:
In beiden Fällen müssen Sie zur Verwendung des Index ohne Berücksichtigung der Groß- und Kleinschreibung dieselbe Sortierung in der
find
Operation angeben , die beim Erstellen des Index oder der Auflistung verwendet wurde:Dies gibt "New York", "New York", "New York" usw. zurück.
Weitere Hinweise
username: 'bill'
passendenBILL
oderBill
nicht eine Volltextsuchabfrage, die auch Spiel würde stammten Wortebill
wieBills
,billed
usw.Die Antworten, die die Verwendung regulärer Ausdrücke vorschlagen, sind langsam, da in der Dokumentation selbst bei Indizes Folgendes angegeben ist :
$regex
Antworten bergen auch das Risiko einer Benutzereingabe .quelle
quelle
TL; DR
Richtiger Weg, dies in Mongo zu tun
Verwenden Sie RegExp nicht
Gehen Sie natürlich und verwenden Sie Mongodbs eingebaute Indizierung, suchen Sie
Schritt 1 :
Schritt 2 :
Sie müssen einen Index für jedes TEXT- Feld erstellen, das Sie durchsuchen möchten, ohne dass die Abfrage indiziert wird. Dies ist äußerst langsam
Schritt 3 :
quelle
username: 'bill'
passendenBILL
oderBill
nicht eine Volltextsuchabfrage, die auch Spiel würde Worte stammte vonbill
, wieBills
,billed
usw.quelle
$existing = Users::masterFind('all', ['conditions' => ['traits.0.email' => ['$regex' => "^$value$", '$options' => 'i']]]);
Mongo (aktuelle Version 2.0.0) erlaubt keine Suche ohne Berücksichtigung der Groß- und Kleinschreibung für indizierte Felder - siehe deren Dokumentation . Für nicht indizierte Felder sollten die in den anderen Antworten aufgeführten regulären Ausdrücke in Ordnung sein.
quelle
Eine sehr wichtige Sache, die Sie bei der Verwendung einer Regex-basierten Abfrage beachten sollten: Wenn Sie dies für ein Anmeldesystem tun, maskieren Sie jedes einzelne gesuchte Zeichen und vergessen Sie die Operatoren ^ und $ nicht. Lodash hat eine nette Funktion dafür , falls Sie es bereits verwenden:
Warum? Stellen Sie sich einen Benutzer vor,
.*
der seinen Benutzernamen eingibt. Das würde mit allen Benutzernamen übereinstimmen und eine Anmeldung ermöglichen, indem nur das Passwort eines Benutzers erraten wird.quelle
Die beste Methode ist in der Sprache Ihrer Wahl. Wenn Sie einen Modell-Wrapper für Ihre Objekte erstellen, lassen Sie Ihre save () -Methode eine Reihe von Feldern durchlaufen, nach denen Sie suchen und die ebenfalls indiziert sind. Diese Felder sollten Gegenstücke in Kleinbuchstaben enthalten, die dann für die Suche verwendet werden.
Jedes Mal, wenn das Objekt erneut gespeichert wird, werden die Eigenschaften in Kleinbuchstaben überprüft und mit Änderungen an den Haupteigenschaften aktualisiert. Auf diese Weise können Sie effizient suchen, aber die zusätzliche Arbeit, die zum Aktualisieren der lc-Felder jedes Mal erforderlich ist, verbergen.
Die Felder in Kleinbuchstaben können ein Schlüssel sein: Wert Objektspeicher oder nur der Feldname mit dem Präfix lc_. Ich verwende die zweite, um die Abfrage zu vereinfachen (tiefe Objektabfragen können manchmal verwirrend sein).
Hinweis: Sie möchten die lc_-Felder indizieren, nicht die Hauptfelder, auf denen sie basieren.
quelle
Angenommen, Sie möchten "Spalte" in "Tabelle" suchen und möchten eine Suche ohne Berücksichtigung der Groß- und Kleinschreibung durchführen. Der beste und effizienteste Weg ist wie folgt;
Der obige Code fügt nur Ihren Suchwert als RegEx hinzu und sucht mit unempfindlichen Kriterien, die mit "i" als Option festgelegt sind.
Alles Gute.
quelle
Mit Mongoose hat das bei mir funktioniert:
quelle
.toLowerCase()
redundant, wenn Sie das Flag ohne Berücksichtigung der Groß- und Kleinschreibung angebeni
?Das Aggregations-Framework wurde in Mongodb 2.2 eingeführt. Sie können den Zeichenfolgenoperator "$ strcasecmp" verwenden, um einen Vergleich zwischen Zeichenfolgen ohne Berücksichtigung der Groß- und Kleinschreibung durchzuführen. Es ist empfehlenswerter und einfacher als die Verwendung von Regex.
Hier ist das offizielle Dokument zum Aggregationsbefehlsoperator: https://docs.mongodb.com/manual/reference/operator/aggregation/strcasecmp/#exp._S_strcasecmp .
quelle
Sie können Indizes verwenden, bei denen die Groß- und Kleinschreibung nicht berücksichtigt wird :
Im folgenden Beispiel wird eine Sammlung ohne Standardkollatierung erstellt und anschließend ein Index für das Namensfeld mit einer Sortierung hinzugefügt, bei der die Groß- und Kleinschreibung nicht berücksichtigt wird. Internationale Komponenten für Unicode
Um den Index verwenden zu können, müssen Abfragen dieselbe Sortierung angeben.
oder Sie können eine Sammlung mit Standardkollatierung erstellen:
quelle
db.users.createIndex( { name: 1 }, {collation: { locale: 'tr', strength: 2 } } )
Zum Suchen und Entkommen einer Variablen:
Das Escaping der Variablen schützt die Abfrage vor Angriffen mit '. *' Oder einem anderen regulären Ausdruck.
Escape-String-Regexp
quelle
Verwenden Sie RegExp . Falls andere Optionen für Sie nicht funktionieren, ist RegExp eine gute Option. Dadurch wird die Groß- und Kleinschreibung der Zeichenfolge nicht berücksichtigt.
Verwenden Sie den Benutzernamen in Abfragen, und dann ist es fertig.
Ich hoffe es wird auch für dich funktionieren. Alles Gute.
quelle
Ich habe eine einfache Funktion für die Groß- und Kleinschreibung erstellt, die ich in meinem Filter verwende.
Dann filtern Sie einfach wie folgt nach einem Feld.
quelle
Die Verwendung eines Filters funktioniert bei mir in C #.
Möglicherweise wird sogar der Index verwendet, da ich glaube, dass die Methoden nach der Rückgabe aufgerufen werden, aber ich habe dies noch nicht getestet.
Dies vermeidet auch ein Problem von
Dieser Mongodb wird denken, dass p.Title.ToLower () eine Eigenschaft ist und nicht richtig zugeordnet wird.
quelle
Für alle, die Golang verwenden und eine Volltextsuche mit Groß- und Kleinschreibung mit mongodb und der mgo godoc globalsign Bibliothek wünschen .
quelle
Wie Sie in Mongo-Dokumenten sehen können - da der
$text
Index der Version 3.2 standardmäßig nicht zwischen Groß- und Kleinschreibung unterscheidet: https://docs.mongodb.com/manual/core/index-text/#text-index-case-insensitivityErstellen Sie einen Textindex und verwenden Sie den $ text-Operator in Ihrer Abfrage .
quelle
username: 'bill'
passendenBILL
oderBill
nicht eine Volltextsuchabfrage, die auch Spiel würde Worte stammte vonbill
, wieBills
,billed
usw.Diese wurden für die Suche nach Zeichenfolgen getestet
quelle
Ich hatte ein ähnliches Problem und das hat bei mir funktioniert:
quelle
$regex
als auch$options
. Was hast du Strg + F?$regex
ineffizient und möglicherweise unsicher, wie ich in meiner Bearbeitung zu dieser anderen Antwort von 2016 erläutert habe . Es ist keine Schande, Antworten zu löschen, wenn sie nicht mehr der Community dienen!