PyMongo $in + $регулярное выражение

Как я могу объединить $regex с $in в PyMongo?

Я хочу найти /*.heavy.*/ или /*.metal.*/.

Я пробовал в питоне безуспешно:

db.col.find({'music_description' : { '$in' : [ {'$regex':'/*.heavy.*/'} ]} })

Эквивалент в оболочке Mongo:

db.inventory.find( { music_description: { $in: [ /heavy/, /metal/ ] } } )

person Diolor    schedule 08.11.2013    source источник


Ответы (2)


Используйте регулярные выражения Python.

import re
db.col.find({'music_description': {'$in': [ re.compile('.*heavy.*'), re.compile('.*metal.*')]}})
person user2998367    schedule 16.12.2013
comment
Хм. Работает как шарм. Каким-то образом, как это ни уместно, это также не совсем очевидно - какая-то строка регулярного выражения казалась более очевидным выбором (я полагаю, из-за преобразования строки в скомпилированное регулярное выражение, а затем обратно в строку для bson). Спасибо за ваше сообщение. - person Mr. B; 16.09.2014

Зачем вообще использовать $in? Вы тратите впустую обработку, оценивая поле для каждого значения в списке, и, поскольку каждое значение является регулярным выражением, оно имеет свои собственные соображения производительности. В зависимости от того, как долго ваши строки запроса, может быть разумно просто обернуть их в один регулярное выражение и избегайте запроса $in вместе

import re
db.col.find({'music_description': re.compile('heavy|metal')})

аналогично в оболочке монго

db.inventory.find({music_description: /heavy|metal/})

что касается ответа [user2998367], вы тратите эффективность впустую, компилируя регулярное выражение с жадными подстановочными знаками с единственной целью совпадения, разница между re.search и re.match в python требует использования подстановочных знаков для re.search целей, но re.match ведет себя как «где угодно в строке», как и MongoDB, он действительно нужен только в том случае, если вы собираетесь извлечь, что вам нужно будет сделать позже после запроса в любом случае, или если вы повторно используете скомпилированный регулярное выражение в другом месте, где вам особенно нужен re.search вместо re.match

person apocolipse    schedule 14.04.2015
comment
он пытается проверить элементы массива, а не саму music_description. - person JSBach; 12.11.2015
comment
Запрос $in является довольно гибким и имеет множество применений. Во-первых, это очевидный вариант использования, который читается как «Некоторое левое значение находится в этом массиве возможных правых значений, и это то, что он, кажется, запрашивает здесь (имя music_description никоим образом не указывает, что это массив значений. ..) Другое использование - это то, о чем вы думаете, левое значение этого массива содержит одно или любое из этих правых значений, которые также могут быть записаны как db.s.find({'someArray': {$in: oneValue}}) вместо массива, наконец, также как db.s.find({'someArray': oneValue}) для краткости - person apocolipse; 14.11.2015
comment
...продолжение И для целей этого запроса, поскольку правые значения являются регулярными выражениями, практически нет смысла обрабатывать каждое регулярное выражение по отдельности, а скорее просто сопоставлять их как одно - person apocolipse; 14.11.2015