使用Python嵌套复杂查询MongoDB

时间:2018-01-23 13:12:49

标签: python mongodb aggregation-framework

我的MongoDB中有以下文档:

{
    "_id" : ObjectId("5a672fe5c9afd19e04d011ca"),
    "data" : [ 
        {
            "name" : "Smith",
            "age" : 10,
            "spouse" : "Lopez"
        }, 
        {
            "name" : "Davis",
            "age" : 10,
            "spouse" : "Peter"
        }, 
        {
            "name" : "Clark",
            "age" : 10
        }
    ],
    "header" : {
        "sourece" : "http://www.some.com/api/json/data?department=security&gender=female",
        "fetch_time" : "2018-01-23T09:35:51"
    }
}

现在我想:

  1. 获取"数据"下的所有数据节点。
  2. 让所有拥有的人 "配偶"节点
  3. 以下代码无效:

    from pymongo import MongoClient
    from pprint import pprint
    
    client = MongoClient('mongodb://localhost:27017/')
    db = client['test']
    coll = db['test_2']
    
    print('All content:')
    for item in coll.find():
        pprint(item)
    
    print('-'*20)
    print("Content under 'data':")
    for item in coll.find({"data": "$all"}):
        pprint(item)
    
    for item in coll.find({"data": []}):
        pprint(item)
    
    for item in coll.find({"data": ["$all"]}):
        pprint(item)
    
    print('-'*20)
    print("People who have 'spouse':")
    for item in coll.find({"data": [{"spouse":"$all"}]}):
        pprint(item)
    

    以上代码输出以下内容:

    All content:
    {u'_id': ObjectId('5a672fe5c9afd19e04d011ca'),
     u'data': [{u'age': 10, u'name': u'Smith', u'spouse': u'Lopez'},
               {u'age': 10, u'name': u'Davis', u'spouse': u'Peter'},
               {u'age': 10, u'name': u'Clark'}],
     u'header': {u'fetch_time': u'2018-01-23T09:35:51',
                 u'sourece': u'http://www.some.com/api/json/data?department=security&gender=female'}}
    --------------------
    Content under 'data':
    --------------------
    People who have 'spouse':
    

    我可以从MongoDB获取所有内容,这意味着数据存在于数据库中。但是当我运行后续代码时,没有打印任何内容。我尝试了不同的方法,但没有一种方法有效。

    此外,有没有像Oracle SQL reference.pdf这样的文档说明具有严格结构规范的查询语句语法,所以我可以基于它构建任何查询语句?

1 个答案:

答案 0 :(得分:0)

无需获取所有数据。

第一部分(常规查询) - 阅读here   - 使用投影输出没有查询过滤器的所有数据字段。

coll.find({},{"data": 1})这样的东西。

第二部分(聚合查询) - 阅读here - 使用$match包含“数据”至少有一个数组元素的文档,其中包含配偶字段,后跟$filter $type表达式,用于检查$project匹配数组元素的缺失字段。

这样的东西
col.aggregate([
  {"$match":{"data.spouse":{"$exists":true}}},
  {"$project":{
    "data":{
      "$filter":{
        "input":"$data",
        "as":"result",
        "cond":{"$ne":[{"$type":"$$result.spouse"},"missing"]
        }
      }
    }
  }}
])

query operators也不是aggregation comparison operators