【问题标题】:Filter arrays against multiple regex matches针对多个正则表达式匹配过滤数组
【发布时间】:2014-09-28 17:51:24
【问题描述】:

我想搜索 MongoDB,以便仅获得在键元素的某些配置中找到所有 x 的结果。这是this previous question的延续。

collected = []                              # Initialize an empty list

for x in input:                             # Iterate over input
  collected.append(re.compile(x))           # Append re.compile object to list

cursor = db.collection.find({"key": {"$all": collected}})

现在它返回输入列表元素出现在所提供键的任何元素中的所有文档。如何仅获取输入列表元素出现在键元素中的结果?

例如当

input = ['A', 'B', 'C', 'D']

它会返回一个带有

的文档
key = ['AHBKCOD', 'NDSI']

但不是

key = ['A', 'B', 'C', 'D', 'AB']

返回匹配元素会很棒,例如'AHBKCOD' 也是直接的。

【问题讨论】:

    标签: python regex mongodb pymongo


    【解决方案1】:

    Mongo Shell 示例

    设置测试数据:

    > db.test.insert({'key': ['AHBKCOD', 'NDSI']})
    > db.test.insert({'key': ['A', 'B', 'C', 'D', 'AB']})
    

    您当前的查询确实匹配两条记录,所以$all 不是我们想要的运算符:

    > db.test.find({"key": {"$all": [/A/, /B/, /C/, /D/]}}, {'_id': 0})
    { "key" : [  "AHBKCOD",  "NDSI" ] }
    { "key" : [  "A",  "B",  "C",  "D",  "AB" ] }
    

    要匹配包含一组正则表达式的字符串并重组返回对象,您需要使用aggregation framework。此查询所需的操作是$unwind$match、$and$project

    > db.test.aggregate([{"$unwind": "$key"}, 
                         {"$match": {"$and": [{"key": /A/}, 
                                              {"key": /B/}, 
                                              {"key": /C/}, 
                                              {"key": /D/}]}}, 
                         {"$project": {"_id": 0, "key": "$key"}}])
    

    这将只返回您想要的密钥:

    { "result" : [ { "key" : "AHBKCOD" } ], "ok" : 1 }
    

    如果您运行的是 mongo 2.6 或更高版本,那么聚合函数将像查找查询一样返回一个游标。在 2.6 以下,您会得到一个带有顶级键 result 和 'ok' 的文档。要提取结果数组,您可以在查询末尾添加["result"]

    [ { "key" : "AHBKCOD" } ]
    

    迁移到 Python

    将其转换为 Python 的工作很少,因为 JSON (和 mongo 扩展的 JSON) 无需过多更改即可使用,因为它们通常是值 Python 结构 (字典,列表) 特别是如果你在引用键时很小心。 Python 没有像 /A/ 这样的正则表达式文字,因此我们需要进行一次更改,将其转换为 re.compile(r'A')

    input = ['A', 'B', 'C', 'D']
    
    collected = [{"key": re.compile(x)} for x in input] 
    
    query = [{"$unwind": "$key"}, 
             {"$match": {"$and": collected}}, 
             {"$project": {"_id": 0, "key": "$key"}}]
    
    result = db.test.aggregate(query)["result"]
    

    我假设您在这里使用的是低于 2.6 的 MongoDB 版本。

    print result
    [{u'key': u'AHBKCOD'}]
    

    对于值列表,您可以使用列表推导:

    print [res['key'] for res in result]
    [u'AHBKCOD']
    

    【讨论】:

      猜你喜欢
      • 2019-10-06
      • 2012-11-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-13
      • 1970-01-01
      • 2013-11-25
      相关资源
      最近更新 更多