我使用python 3.7.1(默认值,2018年12月14日,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"}}}
]}
)
所以在pymongo中,我做的与之相同:
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
。
因此,我按照建议的here进行了尝试:
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.
没有错误。
一些样品
根据Emma的要求,我可以举一个示例,它将在mongo中明确显示我的请求。 通常,我必须在该字段中具有以下模式:
对我来说主要的问题是我的蜘蛛不能正确解析,因为我没有为此编写足够强大的脚本。 我得到的结果不是仅仅获得“ 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"}]
答案 0 :(得分:2)
尝试使用带有否定前瞻性的字符串文字。只要您在'bon'之后有回车符(\ r),下面的示例就可以工作。
import re
bon = re.compile(r'bon(?=\r)')
db.collection.find({'field': bon})
答案 1 :(得分:2)
我只是遇到了同样的问题。
尝试这样做:
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
错误。
我找到了这样的https://stackoverflow.com/a/20175230/9069964,这终于对我有用:
item_name = item["name"]
{item["type"]: {"$not": re.compile(item_name)}}
我不得不放弃“ $ regex”部分,并给“ $ not”我的正则表达式内容。
答案 2 :(得分:0)
在这里,我们也许可以解决此问题,甚至无需使用$not
功能。例如,如果我们不希望bon souple
或bon léger
后面没有空格,则可以使用类似于以下内容的表达式:
bon
我不太确定我们要在此处提取的内容,但是我只是猜测也许我们想在"bon[^\s].+"
之间滑动bon
值,而不用空格。
此外,我们可能希望研究正则表达式查询要求并根据需要调整表达式,例如转义或使用捕获组:
"
或:
(bon[^\s].+)
或:
"(bon[^\s].+)"
或:
\"(bon[^\s].+)\"
jex.im可视化正则表达式:
我不确定这是否是我们想要的,或者是否有意义,但是根据此documentation,我们可以尝试使用:
([\s\S]*?)\"(bon[^\s].+)\"
或:
{ name: { $regex: /([\s\S]*?)\"(bon[^\s].+)\"/, $options: "mi" } }
{ name: { $regex: '([\s\S]*?)\"(bon[^\s].+)\"', $options: "mi" } }
或:
db.collection.find({"field":{ $regex: /(bon[^\s].+)/, $options: "mi" }})
参考: