Выполнение запросов регулярных выражений с помощью pymongo


Я пытаюсь выполнить запрос регулярного выражения с помощью pymongo против сервера mongodb. Структура документа выглядит следующим образом

{
  "files": [
    "File 1",
    "File 2",
    "File 3",
    "File 4"
  ],
  "rootFolder": "/Location/Of/Files"
}

Я хочу получить все файлы, соответствующие шаблону * файл. Я попытался сделать это как таковой

db.collectionName.find({'files':'/^File/'})

но я ничего не получаю обратно, я что-то упускаю, потому что в соответствии с документами mongodb это должно быть возможно. Если я выполняю запрос в консоли mongo, он отлично работает , означает ли это, что api не поддерживает его или я просто использую его неправильно

5 107

5 ответов:

Если вы хотите включить параметры регулярного выражения (например, игнорировать регистр), попробуйте следующее:

import re
regx = re.compile("^foo", re.IGNORECASE)
db.users.find_one({"files": regx})

оказывается, поиск регулярных выражений выполняется немного по-другому в pymongo, но так же просто.

регулярное выражение выполняется следующим образом :

db.collectionname.find({'files':{'$regex':'^File'}})

это будет соответствовать всем документам, которые имеют свойство files, которое имеет элемент внутри, который начинается с File

чтобы избежать двойной компиляции, вы можете использовать оболочку BSON regex, которая поставляется с PyMongo:

>>> regx = bson.regex.Regex('^foo')
>>> db.users.find_one({"files": regx})

Regex просто сохраняет строку, не пытаясь ее скомпилировать, поэтому find_one может затем определить аргумент как тип "Regex" и сформировать соответствующий запрос Mongo.

Я чувствую, что этот способ немного более Питонический, чем другой верхний ответ, например:

>>> db.collectionname.find({'files':{'$regex':'^File'}})

стоит прочитать документацию по регулярному выражению bson, если вы планируете использовать запросы регулярных выражений, потому что есть некоторые предостережения.

import re

def get_pattern_query(pattern,starting_with=False,ending_with=False,ignore_case=False):
    start = '^' if starting_with else '.*'
    end = '$' if ending_with else '.*'
    pattern = start + re.escape(pattern) + end
    return re.compile(pattern, re.IGNORECASE) if ignore_case else re.compile(pattern)

Побег из шаблона перед компиляцией обрабатывает все символы.

решение re не использует индекс вообще. Вы должны использовать такие команды, как:

db.collectionname.find({'files':{'$regex':'^File'}})

(Я не могу комментировать ниже их ответы, поэтому я отвечаю здесь)