mongodb - Mongo $lookup 过滤器使用嵌套查询
问题描述
我正在使用 mongoDB 的 $lookup 函数,特别是管道语法,以允许我执行一些比我使用的 ORM(Sails/Waterline)允许的更复杂的查询。
我的数据的精简版看起来像....
// 'job' collection
{
"id" : j1,
"mediaID" : "ABC1234"
},
{
"id" : j2,
"mediaID" : "DEF1234"
},
{
"id" : j3,
"mediaID" : "FGH3456"
}
..和..
// 'task' collection
// j1 tasks
{
"id" : "t1",
"job" : "j1",
"taskName": "MOVE",
"status" : "COMPLETE"
},
{
"id" : "t2",
"job" : "j1",
"taskName": "PUBLISH",
"status" : "COMPLETE"
},
// j2 tasks
{
"id" : "t3",
"job" : "j2",
"taskName": "MOVE",
"status" : "FAILED"
},
// j3 tasks
{
"id" : "t4",
"job" : "j3",
"taskName": "MOVE",
"status" : "COMPLETE"
}
..其中任务集合链接到作业集合通过job.id -> task.job
我想要实现的是,能够通过job.mediaID
和/或也过滤工作task.status
。我目前拥有的查询几乎得到了我想要的,但它没有过滤掉jobs
,它只是没有填充tasks
部分。
我目前的查询如下...
let results = await jobCollection.aggregate([
// First filter jobs with matching criteria
{
$match: {
$text: {$search: "1234"}
}
},
// Next, link the task collection, and filter by status
{
"$lookup": {
from : 'task',
'let' : {job_id: '$_id'},
pipeline: [
{
$match: {
$expr: {
$and: [
// This does the linking of job.id -> task.job_id
{$eq: ['$job', '$$job_id']},
// This filters out unwanted tasks
{$eq: ['$status', 'FAILED']}
]
}
}
}
],
as : 'tasks'
}
}
])
.toArray();
在该示例中,第一阶段将匹配j1
并且j2
由于它们都包含“1234”,因此我想根据任务状态进一步过滤掉作业,例如,只有j2
一个具有 的任务status==FAILED
,所以我的最终结果是只是j2
文件。
我希望这能让。我想我可能只需要在最后添加一些巧妙的投影。谢谢
解决方案
内部管道与文档无关$match
。它只过滤要收集的文档。因此,您必须在 之后再使用一个阶段来过滤掉 ROOT( ) 文档。$lookup
jobCollection
tasks
$match
$lookup
jobCollection
jobCollection.aggregate([
{ "$match": { "$text": { "$search": "1234" }}},
{ "$lookup": {
"from": "task",
"let": { "job_id": "$_id" },
"pipeline": [
{ "$match": {
"$expr": {
"$and": [
{ "$eq": ["$job", "$$job_id"] },
{ "$eq": ["$status", "FAILED"] }
]
}
}}
],
"as": "tasks"
}},
{ "$match": { "tasks": { "$ne": [] }}},
])
推荐阅读
- java - Maven 安装任务似乎在编译之前对旧代码运行测试
- python - 暂停调用的函数几秒钟
- c++ - 为什么 CodeChef 在线 ide 在其他在线 ide 上完美运行时,也会为以下插入排序提供 SIGSEGV 错误?
- groovy - Groovy Power Operator (**) 是否在关联性中被破坏?
- java - 在同一个 ec2 上运行多个 tomcat
- c# - 在 Where 子句中使用 Or 和 Select 将所有条目与 int 和 lambda 表达式进行比较
- c++ - 是否有一种(文献)算法将节点拆分为每个传入边缘的一个节点?
- php - 为什么我的表单输入值没有传递到数据库
- python - Python 到 C++ 的字典列表
- javascript - 5分钟后空闲用户注销不能在Angular-7的所有页面上正常工作?