Mongodb聚合查找查询-返回所有子文档
从问题开始,我希望根据关联子文档中的值筛选父文档列表 给定以下mongoDB集合Mongodb聚合查找查询-返回所有子文档,mongodb,aggregation-framework,lookup,Mongodb,Aggregation Framework,Lookup,从问题开始,我希望根据关联子文档中的值筛选父文档列表 给定以下mongoDB集合 //“作业”集合 { “id”:j1, “mediaID”:“ABC1234” }, { “id”:j2, “mediaID”:“DEF1234” } …和 /“任务”集合 //j1任务 { “id”:“t1”, “作业”:“j1”, “任务名称”:“移动”, “状态”:“完成” }, { “id”:“t2”, “作业”:“j1”, “任务名称”:“发布”, “状态”:“失败” }, //j2任务 { “id”:
//“作业”集合
{
“id”:j1,
“mediaID”:“ABC1234”
},
{
“id”:j2,
“mediaID”:“DEF1234”
}
…和
/“任务”集合
//j1任务
{
“id”:“t1”,
“作业”:“j1”,
“任务名称”:“移动”,
“状态”:“完成”
},
{
“id”:“t2”,
“作业”:“j1”,
“任务名称”:“发布”,
“状态”:“失败”
},
//j2任务
{
“id”:“t3”,
“作业”:“j2”,
“任务名称”:“移动”,
“状态”:“完成”
},
{
“id”:“t4”,
“作业”:“j2”,
“任务名称”:“发布”,
“状态”:“完成”
}
..其中任务集合通过job.id->task.job链接到作业集合
我有一个聚合查询,它将根据子集合中的条件筛选job
集合。我正在使用Mongo的$lookup
的管道语法,并有一个类似这样的查询
db.getCollection(“作业”).aggregate(
[
{
“$lookup”:{
“发件人”:“任务”,
“让”:{
“作业id”:“$\U id”
},
“管道”:[
{
“$match”:{
“$expr”:{
“$and”:[
{
//将job.id链接到task.job
“$eq”:[“$job”、“$$job\u id”]
},
{
//筛选器任务名
“$eq”:[“$taskName”,“PUBLISH”]
},
{
//按状态筛选
“$eq”:[“$status”,“FAILED”]
}
]
}
}
}
],
“作为”:“任务”
}
},
{
//删除不符合“任务”条件的根文档
“$match”:{
“任务”:{“$ne”:[]}
}
}
]
);
这很好,只是我希望在结果中返回父级的所有子文档,而不仅仅是匹配的子文档
例如,上面的查询给了我这个
{
“id”:j1,
“mediaID”:“ABC1234”
“任务”:[
{
“id”:“t2”,
“作业”:“j1”,
“任务名称”:“发布”,
“状态”:“失败”
},
]
},
…但是我想要这个
{
“id”:j1,
“mediaID”:“ABC1234”
“任务”:[
{
“id”:“t1”,
“作业”:“j1”,
“任务名称”:“移动”,
“状态”:“完成”
},
{
“id”:“t2”,
“作业”:“j1”,
“任务名称”:“发布”,
“状态”:“失败”
},
]
},
我有一个墨水,我需要在某个时候使用
$push
,但我被难住了!非常感谢您的帮助。您应该将筛选逻辑移出$lookup
,并作为下一个管道阶段运行。在那里,您可以使用运算符检查是否存在具有所需值的子文档:
db.job.aggregate([
{
$lookup: {
from: "task",
localField: "id",
foreignField: "job",
as: "tasks"
}
},
{
$match: {
$expr: {
$anyElementTrue: {
$map: {
input: "$tasks",
in: {
$and: [
{ $eq: [ "$$this.taskName", "PUBLISH" ] },
{ $eq: [ "$$this.status", "FAILED" ] }
]
}
}
}
}
}
}
])
免责声明:您的数据/聚合中有两个不同的字段名:
taskName
和taskCode
。我决定使用第一个。您可以使用$addFields
db.job.aggregate([
{$lookup: {from: 'task', localField: 'id', foreignField: 'job', as: 'taskList'}},
{$addFields: {
tasks: {
$filter: {
input: '$taskList',
as: 't',
cond: { $and: [
{$eq: ['$$t.taskCode', 'PUBLISH']},
{$eq: ['$$t.status', 'FAILED']}
]}
}
}
}},
{$project: {
_id: 1,
mediaID: 1,
tasks: 1
}}
])
然后通过
status
和taskCode
删除过滤器,但它将返回另一个作业
文档!我希望筛选失败的作业,但我仍然需要查看与该作业类型相关的所有任务是否已修复!谢谢,这非常有效,实际上比我以前的方法性能更好(100毫秒),并且达到了我需要的输出。