【发布时间】:2020-09-06 18:38:00
【问题描述】:
我正在尝试加入两个集合并从两个集合中获取字段。集合具有非常基本的结构,它们的外观如下:
"products": [
{
"_id": 0,
"name": "product 0",
"desc": "some product",
"sales_reps": [
{
"sales_rep_id": 0,
"is_doing_good": true
},
{
"sales_rep_id": 1,
"is_doing_good": true
}
]
}
]
"sales_rep_master": [
{
"_id": 0,
"name": "sales rep 0"
},
{
"_id": 1,
"name": "sales rep 1"
},
{
"_id": 2,
"name": "sales rep 2"
}
]
我正在尝试通过products.sales_reps.sales_rep_id = sales_rep_master._id 加入他们。这是我的查询的样子:
[
{
"$match": { <--Filter on product._id
"_id": 0
}
},
{
"$unwind": { <-- Expand sales reps array
"path": "$sales_reps"
}
},
{
"$lookup": { <-- join with sales rep master and filter our where is_doing_well is false
"from": "sales_rep_master",
"let": {
"sr_id": "$sales_reps.sales_rep_id",
"is_doing_well": "$sales_reps.is_doing_good"
},
"pipeline": [
{
"$match": {
"$and": [
{
"$expr": {
"$eq": [
"$_id",
"$$sr_id"
]
}
},
{
"$expr": {
"$eq": [
"$$is_doing_well",
true
]
}
}
]
}
},
{
"$addFields": {
"doing_good": "$$is_doing_well"
}
}
],
"as": "sales_reps"
}
},
{
"$unwind": { <<- expand newly created sales reps array
"path": "$sales_reps"
}
},
{
"$group": { <-- Group product and sales reps
"_id": "$_id",
"product": {
"$first": "$$ROOT"
},
"sales_reps": {
"$push": "$sales_reps"
}
},
},
{
"$set": { <-- add sales_reps inside product
"product.sales_reps": "$sales_reps"
}
},
{
"$replaceRoot": { <-- replace root
"newRoot": "$product"
}
}
]
这个查询工作正常,我得到了预期的输出,但我觉得我在这里做错了,因为这似乎做太多只是为了从两个集合中获取字段。在我排除之后还有更多阶段。
这里是演示:https://mongoplayground.net/p/_Tz3fm4a-J8
我在这里做错了什么还是应该是这样?
【问题讨论】:
-
我只需要知道,
{"$expr":{"$eq":["$$is_doing_well",true]}}你为什么要在管道内部检查这个?管道是使用连接表阶段。is_doing_well在您的product收藏中。所以如果你需要检查is_doing_well:true,你可以在查找之前进行。 mongoplayground.net/p/Jq7ohYeqwub 是否可以帮助您,如果可以,我可以简要回答一下 -
您好@varman 知识,
$in内部查找管道将不会使用索引(如果提供),请查看此 question 并点击链接和票证。 -
@turivishal 我刚刚通过了jira.mongodb.org/browse/SERVER-32549 票。
$unwind当我们知道有数千条记录时,性能会更加糟糕。 -
@turivishal 并且他表示需要匹配两个变量。(可能是他的场景错误,我对此提出质疑)。我可以通过定期查找完成并需要更多阶段
-
@varman 是的,你是正确的 $unwind,看看这个问题,在第一个管道中,他正在使用
_id搜索它只会返回一个文档,其次我认为它不是存储的好方法数千个数组元素,如果数组字段包含有限的数据,那么只为一个文档的数组展开是很好的选择,你的方法非常好,但它取决于 OP 的原始数据。我会检查explainstat 的两种方法。
标签: mongodb mongodb-query