python - MongoDB 2.6 中preserveNullAndEmptyArrays 的解决方法

标签 python mongodb aggregation-framework

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

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

这意味着仅返回包含该字段的文档,其他文​​档将被忽略。我使用的是 PyMongo 2.6,因此无法使用 documentation 中提到的 preserveNullAndEmptyArrays因为它是 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" : [], }
}

最佳答案

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

这里的条件是$eq如果字段为[None],则返回 True;如果条件表达式的计算结果为 false,则返回 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" }
    ]
)

关于python - MongoDB 2.6 中preserveNullAndEmptyArrays 的解决方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38271137/

相关文章:

node.js - Docker - Nodejs 到 Mongodb 连接有效,但集合为空

MongoDB - 如何根据匹配字段对查找进行排序?

mongodb - 使用 Mongo 按组计算多个不同的字段

python - setup.py 脚本使用 find_packages() 与 "requirements.txt"的区别

Python3 - 同情 : expand products of trig functions

python - 使用 mongoengine 将文件上传到 DEFAULT_FILE_STORAGE 而不是 GridFs

MongoDB:按日期/时间获取每个 ID 的最新完整文档

python - 字典中的键和 dict.keys() 中的键有什么区别?

python验证码解码器库

MongoDB - distinct and count,最简单的情况