基于数组中子对象属性的MongoDB聚合管道过滤器
具有以下结构的给定文档:基于数组中子对象属性的MongoDB聚合管道过滤器,mongodb,mongodb-query,nosql,aggregation-framework,Mongodb,Mongodb Query,Nosql,Aggregation Framework,具有以下结构的给定文档: { 'id': 1, name: 'bob', type: 'foo', children: [{'id': 2}, {'id': 3}]} { 'id': 2, name: 'bob', type: 'foo' } { 'id': 3, name: 'bob', type: 'bar' } { 'id': 4, name: 'bob', type: 'foo', children: [{'id': 5}, {'id': 6}]} { 'id': 5, name: 'b
{ 'id': 1, name: 'bob', type: 'foo', children: [{'id': 2}, {'id': 3}]}
{ 'id': 2, name: 'bob', type: 'foo' }
{ 'id': 3, name: 'bob', type: 'bar' }
{ 'id': 4, name: 'bob', type: 'foo', children: [{'id': 5}, {'id': 6}]}
{ 'id': 5, name: 'bob', type: 'foo' }
{ 'id': 6, name: 'bob', type: 'foo' }
我如何编写聚合管道查询来查找所有文档,如果它们有子文档,那么所有子文档的类型都是foo
(父文档的类型是'foo')
补充说明:
是一个对象数组,其属性引用同一集合中的其他文档子对象
- 并非所有文档都有子文档
- 更改文档结构不是一个选项
- 我已经研究了$unwind和$lookup,但是这会导致许多文档,我只希望在这之后有父文档
类型
标准,$match
,以确保管道中随后仅使用具有适当类型
的父文档$lookup
。尽管这似乎没有明确记录,$lookup
可以毫不费力地使用数组中嵌套对象的属性$elemMatch
和一些否定来实现所需的效果id
只是一个占位符,用于连接任何文档,而不是“官方”\u id
mongo字段
这将排除文档1和3,因为3有一个“bar”类型,而1包含它
这可能不是一个最佳的解决方案,我还没有在大型数据集上测试过它。另外,使用
$elemMatch
的最终匹配非常混乱,因此欢迎对此提出改进建议。包括您提出的查询及其结果。我没有有效的查询,因此提出了这个问题。我最接近的方法是进行简单的查找,但是要使匹配对每个嵌套文档都起作用并没有成功。我不清楚这是正确的方法还是其他方法更有效。即使这样做有效,我也不知道这是最优的还是有更简单的方法。我只是不具备mongodb的专业知识。请检查并添加您的查询和结果。@D.SM别担心,我已经用找到的解决方案添加了我自己的答案。我希望它将来对其他人有用。尽管如此,请随意否决。我仍然不觉得我无数次失败的迭代会有助于澄清这个问题,相反,它们会使问题变得更加复杂和混乱。做某事有无数错误的方法,我尝试了很多。
db.getCollection('items').aggregate([
{ $match : { "type": "foo" } },
{
$lookup: {
from: "items",
localField: "children.id",
foreignField: "id",
as: "items"
}
},
{
$match : {
"items": {
$not: {
$elemMatch: {
"type": { $ne: "foo" }
}
}
}
}
}
])