将不同的嵌入式结构投射到同名

时间:2016-07-06 21:26:54

标签: python mongodb pymongo aggregation-framework

我正在编写一个执行这些任务的python脚本:

  • 使用嵌入文档查询MongoDB集合
  • Aggregate和Project更改查询中返回的字段名称以匹配" u _"惯例
  • 通过REST API将值导入ServiceNow

ISSUE:

嵌入式文档的结构不一致。 HOSTNAME字段存储在不同的结构中。

我需要将主机名作为u_hostname返回。我需要$ hostnames.name的值(如果存在)或$ hostname的值(如果存在)。

如何确定是否存在任何一个,并将其作为u_hostname返回?

结构1主机名存储为$ hostnames.name

{
    "_id" : "192.168.1.1",
    "addresses" : {
        "ipv4" : "192.168.1.1"
    },
    "hostnames" : [ 
        {
            "type" : "PTR",
            "name" : "example.hostname.com"
        }
    ]
}

结构2主机名存储为$ hostname

{
    "_id" : "192.168.2.1",
    "addresses" : {
        "ipv4" : "192.168.2.1"
    },
    "hostname" : "helloworld.com",

}

脚本:

查询只返回$ hostname的值,而不是$ hostname.name。

cmp = db['computers'].aggregate([
        {"$project" : {
                "_id":0,
                "u_hostname": "$hostnames.name",
                "u_hostname": "$hostname",
                "u_ipv4": "$addresses.ipv4"
        }}
])

2 个答案:

答案 0 :(得分:1)

您可以使用$ifNull运算符$project"主机名"字段。

cmp = db['computers'].aggregate([
    {"$project": { 
        "u_hostname": {
            "$ifNull": [
                "$hostnames.name", 
                { "$map": { 
                    "input": {"$literal": ["A"]}, 
                    "as": "el", 
                    "in": "$hostname"
                }}
            ]
        }, 
        "_id": 0, 
        "u_ipv4": "$addresses.ipv4"
    }},
    {"$unwind": "$u_hostname"}
])

答案 1 :(得分:1)

您希望在aggregate函数中包含$ unwind,$ group和$ setUnion运算符。它将允许您展平hostnames.name列表,然后将它们与其他主机名联合起来。