我想从 MongoDB 中的文档中检索子文档。我有以下文件:
{
"_id" : "10000",
"password" : "password1",
"name" : "customer1",
"enabled" : true,
"channels" : [
{
"id" : "10000-1",
"name" : "cust1chan1",
"enabled" : true
},
{
"id" : "10000-2",
"name" : "cust1chan2",
"enabled" : true
}
]
}
我想要的结果是:
{
"id" : "10000-1",
"name" : "cust1chan1",
"enabled" : true
}
但是,到目前为止我能做的最好的就是使用以下查询:
db.customer.find({"channels.id" : "10000-1"}, {"channels.$" : 1, "_id" : 0})
但这给了我以下结果:
{
"channels" : [
{
"id" : "10000-1",
"name" : "cust1chan1",
"enabled" : true
}
]
}
有谁知道是否可以编写一个查询来给我想要的结果?任何帮助将不胜感激。
你可以用聚合框架来做。查询将类似于:
db.customer.aggregate([
{$unwind : "$channels"},
{$match : {"channels.id" : "10000-1"}},
{$project : {_id : 0,
id : "$channels.id",
name : "$channels.name",
enabled : "$channels.enabled"}}
])
使用 MongoDB 3.4.4 及更新版本,聚合框架提供了许多可用于返回所需子文档的运算符。
$replaceRoot
阶段将过滤后的子文档提升到顶层并替换所有其他字段。
$filter
运算符,它根据指定的条件选择要返回的数组的子集,即返回仅包含与条件匹配的元素的数组。然后,您可以使用 $arrayElemAt
运算符将单个数组元素转换为文档
总的来说,运行这个聚合操作会产生预期的结果:
db.customer.aggregate([
{ "$replaceRoot": {
"newRoot": {
"$arrayElemAt": [
{ "$filter": {
"input": "$channels",
"as": "channel",
"cond": { /* resolve to a boolean value and determine if an element should be included in the output array. */
"$eq": ["$$channel.id", "10000-1"]
}
} },
0 /* the element at the specified array index */
]
}
} }
])
输出
{
"id" : "10000-1",
"name" : "cust1chan1",
"enabled" : true
}
我知道可能有点晚了,但我遇到了类似的情况,我想出了解决方案。在聚合管道中,您可以先通过匹配子文档过滤掉数据,然后展开嵌套数组字段,然后替换根。
db.customer.aggregate([
[
{ $match: { "channels.id": "10000-1" }},
{ $unwind: "$channels" },
{ $replaceRoot: { newRoot: "$channels" } }
]
])