首页 > 解决方案 > mongodb 查找 match-expr 作为第二个管道步骤

问题描述

我对 mongodb 聚合比较陌生,我有一个小问题:

我想在两个集合之间加入。问题是,外部字段被放置在内部数组中。这意味着我必须展开数组才能进行正确的 $match。在我的 $match 中,我使用 $epxr 和 $eq 来连接展开的文档(这是有意的,因此不是问题)。需要 $expr 来访问原始集合中的变量:

[
  ...
  {
    $lookup: {
      from: 'foreignCollection',
      as: 'field',
      let: {
        localField: '$someComparisonField'
      },
      pipeline: [
        {
          $unwind: '$arr'
        },
        {
          $match: {
            $expr: {
              $eq: [ '$arr.foreignField', '$$localField' ]
            }
          }
        }
      ]
    }
  }
]

但是field,我的结果集中始终是一个空数组。我真的不知道我做错了什么:D

有人能帮我吗?

编辑: 根据要求,两个涉及的集合的一些示例数据:

原始收藏:

{
  ...
  someComparisonField: 1
},
{
  ...
  someComparisonField: 2
}

国外收藏:

{
  ...
  arr: [
    {
      ...
      foreignField: 1
    },
    {
      ...
      foreignField: 1
    },
    {
      ...
      foreignField: 2
    },
  ]
},
{
  ...
  arr: [
    {
      ...
      foreignField: 1
    },
    {
      ...
      foreignField: 2
    },
    {
      ...
      foreignField: 2
    },
  ]
},
{
  ...
  arr: [
    {
      ...
      foreignField: 2
    },
    {
      ...
      foreignField: 1
    },
    {
      ...
      foreignField: 2
    },
  ]
},

编辑2:

我忘了添加一个小细节:在内部管道中使用 $eq,我正在访问一个固定索引,这意味着foreignField实际上看起来像这样:foreignField: [ <value> ]

标签: mongodbaggregation-framework

解决方案


经过一番调查,我得出以下结论:

在进一步阅读之前,我建议阅读我对问题的两个编辑。特别是我的第二次编辑。

似乎 $expr 中的 $eq 根本无法比较固定索引。

这个表达式根本不起作用:

{
  $expr: {
    $eq: [ '$arr.foreignField.0': '$$localField' ]
  }
}

为了解决这个问题,我在这个阶段之前创建了一个投影,它从所需的固定索引中提取值并将其存储在一个新字段中。所以现在内部管道的特定阶段如下所示:

...
{
  $project: {
    value: { $arrayElemAt: [ '$arr.foreignField', 0 ] }
  }
},
{ 
  $match: {
    $expr: {
      $eq: [ '$value', '$$localField' ]
    }
  }
}
...

推荐阅读