Abfragen von MongoDB (über pymongo) in der groß-und Kleinschreibung effizient
Ich bin derzeit auf der Erstellung einer website in python (Pyramide), die erfordert, dass Benutzer sich anmelden und einloggen. Das system ermöglicht den Benutzern einen Benutzernamen wählen, das kann eine Mischung von Großbuchstaben, Kleinbuchstaben und zahlen.
Das problem entsteht, wenn sicherstellen, dass zwei Benutzer nicht versehentlich dieselben Nutzernamen, also in meinem system "randomUser" sollte der gleiche wie "RandomUser" oder "randomuser'.
Leider (in diesem Fall), weil Mongo speichert Zeichenfolgen als groß-und Kleinschreibung, es könnte möglicherweise eine Anzahl von Benutzern mit den 'gleichen' username.
Ich bin mir bewusst, die Methode der Abfrage von mongo für groß-und Kleinschreibung von strings:
db.stuff.find_one({"foo": /bar/i});
Jedoch, dies scheint nicht zu funktionieren, in meiner Abfrage Methode mit pymongo:
username = '/' + str(username) + '/i'
response = request.db['user'].find_one({"username":username},{"username":1})
Ist dies die richtige Art und Weise der Strukturierung der Abfrage für pymongo (nehme ich nicht)?
Diese Abfrage wird immer dann verwendet, wenn Sie ein Benutzerkonto erstellt haben und eingeloggt (wie es ist zu prüfen, ob der Benutzername ist im system vorhanden). Ich weiß, es ist nicht die effizienteste Abfrage, so sollte es egal wenn es nur auf log-ins oder account-Erstellung? Ist es eher wünschenswert, statt etwas zu tun, die den Benutzer zwingen zu wählen, nur kleingeschriebene Benutzernamen (negiert die Notwendigkeit für case-insensitive-Abfragen insgesamt)?
- Beachten Sie, dass dies erfordert einen full table scan - Indizes können nicht mit regulären Ausdrücken verwendet werden, es sei denn, Sie sind groß-und Kleinschreibung und die regex ist relativ zu "den Anfang der Zeile,
^
". - Ich denke du meinst "es sei denn, Sie sind case-Sensitiv"
Du musst angemeldet sein, um einen Kommentar abzugeben.
PyMongo verwendet native python reguläre Ausdrücke in der gleichen Weise wie die mongo-shell verwendet native javascript reguläre Ausdrücke. Schreiben Sie die entsprechende Abfrage von dem, was Sie geschrieben hatte, in die Schale oben, die Sie verwenden würden:
Beachten Sie, dass dies wird vermeiden Sie die Verwendung eines index, die eventuell auf die
name
Feld, jedoch. Ein gemeinsames Muster für case-insensitive Suche oder Sortierung ist ein zweites Feld in Ihrem Dokument, zum Beispielname_lower
, das ist immer gesetzt, wennname
Veränderungen (zu einem kleingeschriebenen version dername
, in diesem Fall). Sie würde dann die Abfrage für ein solches Dokument wie:db.stuff.find_one({'name': re.compile('^' + re.escape(username) + '$', re.IGNORECASE)})
Akzeptierte Antwort ist gefährlich, es passt zu jeder Zeichenfolge, die den Benutzernamen! Die sichere Möglichkeit ist die übereinstimmung der exakten Zeichenfolge:
Sogar sicherer, Flucht der variable keine Sonderzeichen, die möglicherweise Auswirkungen auf die regex-match: