25

現在、ユーザーがサインアップしてログインする必要がある python (pyramid) で Web サイトを作成しています。このシステムでは、ユーザーは大文字、小文字、数字を組み合わせたユーザー名を選択できます。

この問題は、2 人のユーザーが誤って同じユーザー名を共有しないようにするときに発生します。つまり、私のシステムでは、'randomUser' は 'RandomUser' または 'randomuser' と同じでなければなりません。

残念なことに (この場合)、Mongo は大文字と小文字を区別して文字列を保存するため、「同じ」ユーザー名を持つユーザーが多数存在する可能性があります。

大文字と小文字を区別しない文字列についてmongoにクエリを実行する方法を認識しています。

db.stuff.find_one({"foo": /bar/i});

ただし、これは pymongo を使用したクエリ メソッドでは機能しないようです。

username = '/' + str(username) + '/i'
response = request.db['user'].find_one({"username":username},{"username":1})

これはpymongoのクエリを構造化する正しい方法ですか(私はそうではないと思います)?

このクエリは、ユーザー アカウントが作成またはログインされるたびに使用されます (ユーザー名がシステムに存在するかどうかを確認する必要があるため)。これが最も効率的なクエリではないことはわかっていますが、ログインまたはアカウントの作成でのみ使用される場合は問題になるでしょうか? 代わりに、ユーザーに小文字のユーザー名のみを選択するように強制する (大文字と小文字を区別しないクエリの必要性を完全に無効にする) ようなことを行う方が望ましいですか?

4

2 に答える 2

54

PyMongo は、mongo シェルがネイティブの JavaScript 正規表現を使用するのと同じように、ネイティブの Python 正規表現を使用します。上記のシェルで作成したものと同等のクエリを作成するには、次を使用します。

db.stuff.find_one({'name': re.compile(username, re.IGNORECASE)})

nameただし、これにより、フィールドに存在する可能性のあるインデックスの使用が回避されることに注意してください。大文字と小文字を区別しない検索または並べ替えの一般的なパターンは、ドキュメントに 2 番目のフィールドを用意することです。たとえばname_lower、このフィールドは変更されるたびに常に設定されnameます (この場合は、小文字バージョンのnameに)。次に、次のようなドキュメントをクエリします。

db.stuff.find_one({'name_lower': username.lower()})
于 2011-06-07T17:24:01.333 に答える