Как правильно оформить регулярное выражение в pymongo? - PullRequest
3 голосов
/ 29 мая 2019

Я использую Python 3.7.1 (по умолчанию, 14 декабря 2018, 19:28:38) и pymongo 3.7.2.

В mongodb это работает:

db.collection.find(
    {$and:[
    {"field":{$regex:"bon?"}},
    {"field":{$not:{$regex:"bon souple"}}},
    {"field":{$not:{$regex:"bon léger"}}}
    ]}
    )

Такв пимонго я сделал так же, как:

db.collection.find(
    {"$and":[
    {"field":{"$regex":"bon?"}},
    {"field":{"$not":{"$regex":"bon souple"}}},
    {"field":{"$not":{"$regex":"bon léger"}}}
    ]}
    )

, но это указывает pymongo.errors.OperationFailure: $regex has to be a string.

Так что я попробовал это, как предложено здесь :

liste_reg=[
{'field': {'$regex': {'$not': re.compile('bon souple')}}}, 
{'field': {'$regex': {'$not': re.compile('bon léger')}}}, 
{'field': {'$regex': re.compile('bon?')}}
]
rslt=list(
    db.collection.find({"$and":liste_reg})
)

Я заметил, что даже когда нет специального символа, он указывает на ту же ошибку:

liste_reg=[
{'field': {'$regex': {'$not': re.compile('bon souple')}}} #where no special char is present
]
rslt=list(
    db.collection.find({"$and":liste_reg})
)

Поэтому я попытался использовать "/" как:

liste_reg=[
{'field': {'$regex': {'$not':'/bon souple/'}}} #where no special char is present
#even tried re.compile('/bon souple/')
]
rslt=list(
    db.collection.find({"$and":liste_reg})
)

та же ошибкаpymongo.errors.OperationFailure: $regex has to be a string все еще происходит.

Что я могу сделать?

НЕКОТОРЫЕ ОБНОВЛЕНИЯ МОЕГО ИССЛЕДОВАНИЯ РЕШЕНИЯ

ядро ​​проблемы, кажется, с $not, потому что когдаЯ делаю:

liste_reg=[{'field': {'$regex': 'bon?'}}]
rslt=list(
    db.collection.find({"$and":liste_reg})
)
len(rslt)#gives 23 013, what is ok.

Нет ошибки.

НЕКОТОРЫЕ ОБРАЗЦЫ

По просьбе Эммы я могу дать образец, и он откроет мой запрос на монго.Обычно я должен иметь следующие условия в поле:

  • сек
  • très léger
  • léger
  • bon léger
  • bon
  • сладкий суп
  • суп
  • суп суп
  • коллан
  • тыква
  • тыква
  • profond

Основная проблема для меня заключается в том, что мой паук неправильно проанализировал, потому что я не написал для этого достаточно сильный скрипт.Вместо того, чтобы получать просто «bon», я получаю такой результат:

{"_id":"ID1",
"field":"bon\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\tnon",
...}

, и это пример между многими другими неправильными разборками.Вот почему я хочу, чтобы результат начинался с "bon?", но не с "bon souple" или "bon léger", потому что они имеют правильные значения, а не \n или \t.

Так как образцы:

[{"_id":"ID1",
"field":"bon\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\tnon"},
{"_id":"ID2",
"field":"bon\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\tpremière"},
{"_id":"ID3",
"field":"bon\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t2ème"},
{"_id":"ID4",
"field":"bon souple"},
{"_id":"ID5",
"field":"bon léger"}]

Ответы [ 3 ]

2 голосов
/ 30 мая 2019

Попробуйте использовать строковый литерал с отрицательным взглядом вперед.Пример ниже должен работать, пока у вас есть возврат каретки (\ r) после 'bon'.

import re
bon = re.compile(r'bon(?=\r)')
db.collection.find({'field': bon})
2 голосов
/ 30 мая 2019

Я только что столкнулся с этой же проблемой.

Попробуйте сделать это:

liste_reg=[
{'field': {'$not': re.compile('bon souple')}}, 
{'field': {'$not': re.compile('bon léger')}}, 
{'field': {'$regex': re.compile('bon?')}}
]
rslt=list(
    db.collection.find({"$and":liste_reg})
)

Я только что удалил часть запроса $regex.

Фон

Я попытался сделать {item["type"]: {"$not": item['name']}}, и pymongo вернул ошибку $not needs a regex or a document.

Итак, я попытался: {item["type"]: {"$not": {"$regex": item['name']}}} и pymongo вернул ошибку $not cannot have a regex.

Я нашел это SO https://stackoverflow.com/a/20175230/9069964 и вот что наконец-то сработало для меня:

item_name = item["name"]
{item["type"]: {"$not": re.compile(item_name)}}

Мне пришлось отбросить часть "$ regex" и дать "$ not" мой материал для регулярных выражений.

0 голосов
/ 29 мая 2019

Здесь мы могли бы подойти к решению этой проблемы, возможно, без использования функции $not. Например, если мы хотим, чтобы не было bon souple или bon léger, за которыми bon следовал бы пробел, мы могли бы использовать выражение, подобное:

"bon[^\s].+"

DEMO

Я не очень уверен в том, что мы хотим извлечь здесь, но я просто догадывался, что, возможно, мы захотим провести пальцем по bon значениям без пробела и между ".

Кроме того, мы, вероятно, захотим изучить требования к регулярным выражениям и при необходимости скорректировать наши выражения к ним, например, с помощью экранирования или использования группы захвата:

(bon[^\s].+)

или:

"(bon[^\s].+)"

или

\"(bon[^\s].+)\" 

или:

([\s\S]*?)\"(bon[^\s].+)\"

DEMO

RegEx Circuit

jex.im визуализирует регулярные выражения:

enter image description here


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

{ name: { $regex: /([\s\S]*?)\"(bon[^\s].+)\"/, $options: "mi" } }

или

{ name: { $regex: '([\s\S]*?)\"(bon[^\s].+)\"', $options: "mi" } }

db.collection.find

db.collection.find({"field":{ $regex: /(bon[^\s].+)/, $options: "mi" }})

или:

db.collection.find({"field":{ $regex: /(bon[^\s].+)/, $options: "si" }})

Ссылка:

PyMongo $ in + $ regex

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

...