查询MongoDB关联数组

时间:2016-06-13 18:02:59

标签: python mongodb pymongo aggregation-framework

我正在编写一个python脚本来查询MongoDB数据库。我需要协助查询,过滤和解析存储在关联数组中的数据。

要求:

  • 查询主机名,上次查看日期,状态和IPV4地址(不需要其他字段)

  • 将数据解析为" flat"可以导入关系数据库的json格式

以下是我们要查询的数据的数据结构:

[{"hostnames": [{"type": "ABC", "name": "example.hostname.com"}], "vendor": {"vendor_name": "apple"}, "last_seen": {"$date": 1461123503979}, "status": {"state": "up", "reason": "echo-reply"}, "addresses": {"ipv4": "192.168.1.1"}}]

这是我想要的更简单的数据结构,可以导入到平面关系数据库中:

[{"name": "example.hostname.com", "vendor": "apple", "$date": 1461934503972, "state": "up", "ipv4": "192.168.1.1"}]

这是我开始的代码。我正在使用Aggregation为字段创建别名。

我仍然需要遍历关联数组以检索所需格式的数据。

client = MongoClient(mongo_uri)

db = client[mongo_db]

computers = db['computer'].aggregate([

#Aggregate - RDBMS equivalent to Alias select x as y
#Rename fields to match destination names
       {"$project": {
               "_id":0,
               "u_id":"$id",
               "u_status": "$status",
               "u_vendor":"$vendor",
               "u_addresses": "$addresses",
               "u_hostnames": "$hostnames",
               "u_last_seen": "$last_seen"
       }}
    ])

1 个答案:

答案 0 :(得分:1)

您需要$unwind“hostnames”数组或使用$arrayElemAt运算符访问数组中元素的“name”字段,具体取决于您的服务器版本。

最佳方法是在MongoDB 3.2中使用$project阶段中的$arrayElemAt运算符返回数组中的元素,然后使用$let运算符将其设置为变量并访问带有点表示法的“名称”字段。

computers.aggregate([
    {"$project": {
        "name": { 
        "$let": {
            "vars": {"host": {"$arrayElemAt": ["$hostnames", 0]}}, 
            "in": "$$host.name"}
        }, 
        "vendor": "$vendor.vendor_name", 
        "date": "$last_seen.date", 
        "state": "$status.state", 
        "ipv4": "$addresses.ipv4", 
        "_id": 0
    }}
])

在旧版本中,您需要在$unwind文档之前使用$project运算符解构数组。

computers.aggregate([
    {"$unwind": "$hostnames"},  
    {"$project": {
        "name": "$hostnames.name", 
        "vendor": "$vendor.vendor_name", 
        "date": "$last_seen.date", 
        "state": "$status.state", 
        "ipv4": "$addresses.ipv4", 
        "_id": 0
    }}
])