Виконання регулярних запитів з pymongo


129

Я намагаюся виконати запит регулярного вибору, використовуючи pymongo на сервері mongodb. Структура документа така

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

Я хочу отримати всі файли, які відповідають шаблону * Файл. Я намагався робити це як таке

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

Але я нічого не повертаю, я щось пропускаю, тому що згідно з документами mongodb, це має бути можливим. Якщо я виконую запит на консолі mongo, він працює добре, чи означає це, що api не підтримує його, чи я просто використовую його неправильно

Відповіді:


191

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

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

8
Зауважимо також, що закріплений на початку регекс (тобто: починаючи з ^) може використовувати індекси в db, і в цьому випадку буде працювати набагато швидше.
drevicko

1
Regex, починаючи з ^, може використовувати індекс лише у певних випадках . Під час використання re.IGNORECASE я вважаю, що монго не може використовувати індекс для виконання запиту.
nonagon

Це десь задокументоване використання? Я не можу знайти це в офіційному документі API Pymongo.
Hieu

153

Виявляється, пошук за допомогою регулярних виразів у Pymongo робиться дещо інакше, але так само просто.

Регекс робиться наступним чином:

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

Це буде відповідати всім документам, які мають властивість файлів, у яких є елемент, що починається з File


9
Насправді, у вас тут є також те, як це робиться в JavaScript (і, мабуть, і в інших мовах), якщо ви використовуєте $regex. @ Відповідь Еріка - це спосіб пітона, який трохи інакше.
drevicko

яка різниця? Вони обидва використовують python pymongo правильно? Це частина запитів mongodb, тому я не бачу проблеми.
Декстер

10
Ігнорація можлива в регулярному вираженні mongodb JScript також viz. db.collectionname.find ({'files': {'$ regex': '^ Файл', '$ options': 'i'}})
Ajay Gupta

5
Ця відповідь краще виглядає на моїх очах. Навіщо займатись компілюванням Python RE, якщо ви просто збираєтеся впорядкувати його, щоб Mongo міг скомпілювати його знову? $regexОператор Монго бере $optionsаргументи.
Марк Е. Хааз

3
Будь ласка, використовуйте r'^File'замість цього, '^File'щоб уникнути іншої проблеми
Aminah Nuraini

9

Щоб уникнути подвійної компіляції, ви можете використовувати оболонку bge 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 Regex, якщо ви плануєте використовувати запити регулярного вибору, оскільки є деякі застереження.


1
Якщо вам потрібно узгодити масив з використанням $ in, то $ regex для вас не підійде. bson.regex.Regex зробить трюк!
odedfos

4

Рішення reне використовує індекс взагалі. Вам слід використовувати такі команди, як:

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

(Я не можу коментувати їх відповіді, тому відповідаю тут)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.