我在Mongodb中有一个严重嵌套的文档,遵循以下顺序:
网站 - >房间 - > ups - > batteryStrings - >电池。
我试图通过batteryString _id
字段仅返回匹配的batteryStrings及其电池。
db.getCollection('sites').find({
"rooms.ups.batteryStrings._id": ObjectId("55dc967efefd4e6a14332019")
}, {
"rooms.ups.batteryStrings.batteries.$": 1,
"siteName": 1
}
)
我得到以下2个batteryStrings。我只想返回第二个batteryString(以黄色突出显示)及其电池。
我最初尝试这个但得到了相同的结果:
db.getCollection('sites').find({
"rooms.ups.batteryStrings._id": ObjectId("55dc967efefd4e6a14332019")
}, {
"rooms.ups.batteryStrings.$": 1,
"siteName": 1
})
答案 0 :(得分:2)
您可以尝试使用 aggregation framework 来获得所需的结果。管道需要使用初始的 $match
运算符,该运算符会过滤掉不需要的文档以进入管道。获得所需文档后,您将在数组字段上运行多个 $unwind
运算符,以便为数组字段中的每个元素输出文档,以便在下一个管道步骤中使用。以下管道需要使用 $match
运算符从解构数组中过滤其他文档,然后为您提供所需的文档。管道的最后一步 $project
,然后重新整形流中的每个文档,例如添加新字段或删除现有字段。对于每个输入文档,输出一个文档。因此,以下管道将为您提供结果:
db.sites.aggregate([
{
"$match": {
"rooms.ups.batteryStrings._id": ObjectId("55dc967efefd4e6a14332019")
}
},
{ "$unwind": "$rooms" },
{ "$unwind": "$rooms.ups" },
{ "$unwind": "$rooms.ups.batteryStrings" },
{
"$match": {
"rooms.ups.batteryStrings._id": ObjectId("55dc967efefd4e6a14332019")
}
},
{
"$project": {
"siteName": 1,
"batteryStrings": "$rooms.ups.batteryStrings"
}
}
])
运行管道操作会产生结果:
/* 0 */
{
"result" : [
{
"_id" : ObjectId("5613c98a645a64b1a70af2c1"),
"siteName" : "OGG",
"batteryStrings" : {
"name" : "String 1",
"ctrlId" : "bmstest11",
"_id" : ObjectId("55dc967efefd4e6a14332019"),
"batteries" : [
{
"name" : "String 2a",
"ctrlId" : "bmstest11",
"_id" : ObjectId("55e67b28010000880ca4c045")
},
{
"name" : "String 2b",
"ctrlId" : "bmstest11",
"_id" : ObjectId("55ea1b520100006d004e602a")
},
{
"name" : "String 2c",
"ctrlId" : "bmstest11",
"_id" : ObjectId("55ea1b520100006d004e602b")
}
]
}
}
],
"ok" : 1
}