programing

MongoDB(pymongo를 통해)를 효율적으로 인식하지 못하는 경우 쿼리

minimums 2023. 7. 2. 19:10
반응형

MongoDB(pymongo를 통해)를 효율적으로 인식하지 못하는 경우 쿼리

저는 현재 사용자가 등록하고 로그인해야 하는 파이썬(pyramid) 웹사이트를 만들고 있습니다.이 시스템을 통해 사용자는 대문자, 소문자 및 숫자가 혼합된 사용자 이름을 선택할 수 있습니다.

이 문제는 두 사용자가 실수로 동일한 사용자 이름을 공유하지 않도록 할 때 발생합니다. 즉, 내 시스템의 '랜덤'에서User'는 'Random User' 또는 'Random User'와 같아야 합니다.

안타깝게도 (이 경우) 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는 mongo 쉘이 네이티브 javascript 정규 표현을 사용하는 것과 같은 방식으로 네이티브 python 정규 표현을 사용합니다.위의 셸에 작성한 내용에 해당하는 쿼리를 작성하려면 다음을 사용합니다.

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

이렇게 하면 다음에 있는 인덱스를 사용할 수 없습니다.name그러나 필드.대소문자를 구분하지 않는 검색 또는 정렬의 일반적인 패턴은 문서에 두 번째 필드가 있는 것입니다.name_lower언제든지 설정됩니다.name변경 사항(낮은 경우 버전으로 변경)name이 경우).그런 다음 다음과 같은 문서를 쿼리합니다.

db.stuff.find_one({'name_lower': username.lower()})

승인된 답변은 위험합니다. 사용자 이름이 포함된 문자열과 일치합니다!안전한 옵션은 정확한 문자열과 일치하는 것입니다.

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

정규식 일치에 영향을 줄 수 있는 특수 문자 변수를 피하는 것이 더욱 안전합니다.

import re
db.stuff.find_one({'name': re.compile('^' + re.escape(username) + '$', re.IGNORECASE)}) 

대소문자 구분:

db.stuff.find_one({'name': {'$regex': f'^{username}$'}})

대소문자 구분 안 함:

db.stuff.find_one({'name': {'$regex': f'^{username}$', "$options": 'i'}})

언급URL : https://stackoverflow.com/questions/6266555/querying-mongodb-via-pymongo-in-case-insensitive-efficiently

반응형