我正在使用Python脚本来查询MongoDB集合。该集合包含具有不同结构的嵌入式文档。
我试图简单地“$ unwind”包含在几个文档中的数组。但是,该数组不在所有文档中。
这意味着只返回包含该字段的文档,其他文档将被忽略。我正在使用PyMongo 2.6,因此我无法使用documentation中提到的preserveNullAndEmptyArrays
,因为它是MongoDB 3.2中的新功能
这有解决方法吗? “如果田野路径存在,放松”的话。
有问题的文件和代码的结构在这个单独的部分中有详细说明,但我之前曾问过related question。
ISSUE:
我正在尝试“$ 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"}
])
我遗漏了所有“hostnames”为空数组的文档。
以下是仍然缺失的文档的结构。
结构3
{
"_id" : "192.168.1.1",
"addresses" : { "ipv4" : "192.168.1.1" },
"hostnames" : [], }
}
答案 0 :(得分:1)
我们仍然可以通过使用$ifNull
运算符来保留缺少数组字段的所有文档,并使用逻辑$cond
ition处理为新计算的字段赋值。
此处的条件为$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" }
]
)