[
{
item: "journal",
instock: [
{
warehouse: "A",
qty: 5,
items: null
},
{
warehouse: "C",
qty: 15,
items: [
{
name: "alexa",
age: 26
},
{
name: "Shawn",
age: 26
}
]
}
]
}
]
db.collection.find({
"instock.items": {
$elemMatch: {
name: "alexa"
}
}
})
这将返回整个items数组,因为我只想要带有一个项{name:'alexa',age:26}的items数组
答案 0 :(得分:2)
您可以使用.aggregate(pipeline)
函数。
您的代码如下:
db.collection.aggregate([{
$unwind: {
path: "$instock"
}
}, {
$unwind: {
path: "$instock.items"
}
}, {
$replaceRoot: {
newRoot: "$instock.items"
}
}, {
$match: {
name: "alexa"
}
}])
此管道中使用的命令:
$ unwind -将项目数组解构为多个文档,这些文档都包含原始文档的原始字段,但展开的字段现在具有数组中所有解构对象的值。
$ replaceRoot -获取newRoot
上引用的内部对象,并将其作为文档。
$ match -一种通过某种条件过滤最终生成的文档列表的方法。基本上是.find()
函数中的第一个参数。
有关聚合的更多信息,请访问MongoDB的网站:
编辑
所需的结果是获取单个项目数组作为响应,以实现只需删除管道中的$replaceRoot
阶段即可。
最终管道:
db.collection.aggregate([{
$unwind: {
path: "$instock"
}
}, {
$unwind: {
path: "$instock.items"
}
}, {
$match: {
"instock.items.name": "alexa"
}
}])
答案 1 :(得分:1)
一种替代方法,其中$filter
是项目阶段的关键。
db.collection.aggregate([
{
$match: {
"instock.items.name": "alexa"
}
},
{
$unwind: "$instock"
},
{
$project: {
"item": "$item",
qty: "$instock.qty",
warehouse: "$instock.warehouse",
items: {
$filter: {
input: "$instock.items",
as: "item",
cond: {
$eq: [
"$$item.name",
"alexa"
]
}
}
}
}
},
{
$group: {
_id: "$_id",
instock: {
$push: "$$ROOT"
}
}
}
])
想法是:
$match
作为顶级过滤器$unwind
instock
个数组项来准备$filter
$project
保留其余字段,并在$filter
数组字段上使用items
$group
,因为先前使用过$unwind
。答案 2 :(得分:0)
您必须在投影部分使用$elemMatch
:
db.collection.find({
// whatever your query is
}, {
"instock.items": {
$elemMatch: {
name: "alexa"
}
}
});
更新
Here是这种用法的一个很好的例子。摘自mongodb官方文档。