Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mongodb聚合查找查询-返回所有子文档_Mongodb_Aggregation Framework_Lookup - Fatal编程技术网

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”:

从问题开始,我希望根据关联子文档中的值筛选父文档列表

给定以下mongoDB集合

//“作业”集合
{
“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毫秒),并且达到了我需要的输出。