Выполнение регулярных выражений запросов с pymongo - PullRequest
118 голосов
/ 14 августа 2010

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

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

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

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

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

Ответы [ 5 ]

174 голосов
/ 02 февраля 2011

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

import re
regx = re.compile("^foo", re.IGNORECASE)
db.users.find_one({"files": regx})
139 голосов
/ 14 августа 2010

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

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

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

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

3 голосов
/ 23 мая 2018

Чтобы избежать двойной компиляции, вы можете использовать упаковщик регулярных выражений bson, который поставляется с PyMongo:

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

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

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

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

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

1 голос
/ 16 августа 2018

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

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

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

0 голосов
/ 17 июня 2017
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)

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

...