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 }
  ]
}

假设我要过滤掉符合条件的
股票
s
size='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"] }
      }
    }
  }}
]