【问题标题】:Workaround for preserveNullAndEmptyArrays in MongoDB 2.6MongoDB 2.6 中 preserveNullAndEmptyArrays 的解决方法
【发布时间】:2016-07-08 16:08:15
【问题描述】:

我正在使用 Python 脚本来查询 MongoDB 集合。该集合包含具有不同结构的嵌入式文档。

我试图简单地“$unwind”包含在多个文档中的数组。但是,该数组不在所有文档中。

这意味着只返回包含该字段的文档,其他文​​档被忽略。我正在使用 PyMongo 2.6,所以我无法使用 preserveNullAndEmptyArrays 中提到的 documentation,因为它是 MongoDB 3.2 中的新功能

有解决办法吗?类似于“如果字段路径存在,请放松”。

有问题的文档和代码的结构在此单独但related question我之前问过。

问题:

我正在尝试“$unwind”$hostnames.name 的值。但是,由于该路径并不存在于所有文档中,因此会导致多个文档被忽略。

结构 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",

}

脚本

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"}
])

我缺少所有“主机名”数组为空的文档。

这是仍然缺失的文档的结构。

结构 3

{
   "_id" : "192.168.1.1",
    "addresses" : { "ipv4" : "192.168.1.1" },
    "hostnames" : [], }
}

【问题讨论】:

    标签: python mongodb aggregation-framework


    【解决方案1】:

    我们仍然可以通过使用$ifNull 运算符来保留所有缺少数组字段的文档,并使用逻辑$condition 处理为新计算的字段分配一个值。

    这里的条件是$eq,如果字段是[None],则返回True;如果条件表达式的计算结果为假,则返回False。

    cmp = db['computers'].aggregate(
        [
            {"$project":{ 
                "u_ipv4": "$addresses.ipv4",
                "u_hostname": {
                    "$let": {
                        "vars": {
                            "hostnameName": {
                                "$cond": [
                                    {"$eq": ["$hostnames", []]},
                                    [None], 
                                    {"$ifNull": ["$hostnames.name", [None]]}
                                ]
                            }, 
                            "hostname": {"$ifNull": ["$hostname", None]}
                        }, 
                        "in": {
                            "$cond": [ 
                                {"$eq": ["$$hostnameName", [None]]}, 
                                {"$map": {
                                    "input": {"$literal": [None]}, 
                                    "as": "el", 
                                    "in": "$$hostname"
                                }}, 
                                "$$hostnameName"
                            ]
                        }
                    }
                }
            }},        
            { "$unwind": "$u_hostname" }
        ]
    )
    

    【讨论】:

      猜你喜欢
      • 2015-05-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多