Mongodb 在使用$unwind时,是否可以避免两次使用相同的$match条件?
以以下数据为例:Mongodb 在使用$unwind时,是否可以避免两次使用相同的$match条件?,mongodb,mongodb-query,aggregation-framework,Mongodb,Mongodb Query,Aggregation Framework,以以下数据为例: { _id: 1, item: "abc", stock: [ { size: "S", color: "red", quantity: 25 }, { size: "S", color: "blue", quantity: 10 }, { size: "M", color: "blue", quantity: 50 } ] } { _id: 2, item: "def", stock: [ { size: "S",
{
_id: 1,
item: "abc",
stock: [
{ size: "S", color: "red", quantity: 25 },
{ size: "S", color: "blue", quantity: 10 },
{ size: "M", color: "blue", quantity: 50 }
]
}
{
_id: 2,
item: "def",
stock: [
{ size: "S", color: "blue", quantity: 20 },
{ size: "M", color: "blue", quantity: 5 },
{ size: "M", color: "black", quantity: 10 },
{ size: "L", color: "red", quantity: 2 }
]
}
{
_id: 3,
item: "ijk",
stock: [
{ size: "M", color: "blue", quantity: 15 },
{ size: "L", color: "blue", quantity: 100 },
{ size: "L", color: "red", quantity: 25 }
]
}
假设我要过滤掉符合条件的股票ssize='L'
。我在stock.size
字段中已经有了一个多键索引
在聚合管道中,如果我使用以下两个操作:
[{$unwind: {path: "$stock"}},
{$match: {"stock.size": "L"}}]
我将获得所需的结果,但当数据库变得非常大时,$unwind
步骤将不得不扫描整个集合,而不使用现有索引,这是非常低效的
如果我颠倒$unwind
和$match
操作的顺序,$match
将利用索引应用早期筛选,但最终结果将不符合要求:它将获取大小不为L的额外股票
s,但有属于同一项目的同级L码库存
s
我是否必须使用相同的$match
操作两次,即在$unwind
之前和之后,使其同时使用索引并返回正确的结果?是的,您可以在聚合管道中使用两次阶段,但这里只有第一个阶段将使用索引,第二个阶段将执行collscan
[
{ "$match": { "stock.size": "L" }},
{ "$unwind": { "path": "$stock" }},
{ "$match": { "stock.size": "L" }}
]
如果要避免两次错误,请使用聚合
[
{ "$match": { "stock.size": "L" } },
{ "$addFields": {
"stock": {
"$filter": {
"input": "$stock",
"as": "st",
"cond": { "$eq": ["$stock.size", "L"] }
}
}
}}
]