在python和mongo中使用多个$ regex子句创建$ elemMatch查询

时间:2018-10-08 07:52:31

标签: python regex mongodb pymongo

我正在实施本教程How to Speed-Up MongoDB Regex Queries by a Factor of up-to 10 我正在使用最后指定的查询

db.movies.find({
$and:[{
    $text: {
        $search: "Moss Carrie-Anne"
    }},{
    cast: {
        $elemMatch: {$regex: /Moss/, $regex: /Carrie-Anne/}}
    }]}
);

我遇到的问题是如何生成子查询

$elemMatch: {$regex: /Moss/, $regex: /Carrie-Anne/}

使用python编程

到目前为止我的代码

def regexGen(s):
  d={}
  for word in s.split(" "):
    d["$regex"]= "/"+word+"/"  # this will of course save only the last value into the dict

  return (d)


query= {
    "$and":[{
        "$text": {
            "$search": "Moss Carrie-Anne"
        }},{
        "cast": {
            "$elemMatch": regexGen("Moss Carrie-Anne")}
        }
    ]
}

print (query)

#actual
# {'$and': [{'$text': {'$search': 'Moss Carrie-Anne'}}, {'cast': {'$elemMatch': {'$regex': '/Carrie-Anne/'}}}]}

#expected
# {'$and': [{'$text': {'$search': 'Moss Carrie-Anne'}}, {'cast': {'$elemMatch': {'$regex': '/Carrie-Anne/'}, {'$regex': '/Moss/'} }}]}

我在这里显然缺少了一些东西,但无法弄清

1 个答案:

答案 0 :(得分:1)

您可以基于alternation构建动态正则表达式:

{ "$regex" : "|".join([re.escape(word) for word in s.split()]) }

请参见Python demo

import re
s = "Moss Carrie-Anne"
print({ "$regex" : "|".join([re.escape(word) for word in s.split()]) })
# => {'$regex': 'Moss|Carrie\-Anne'}

请注意,Moss|Carrie\-Anne将与MossCarrie-Anne匹配。如果您在文字输入中包含re.escape(和其他正则表达式特殊字符,那么+会有所帮助。