$lookup 管道中的 $match 始终 returns 所有文档,不过滤

$match in $lookup pipeline always returns all the documents, not filtering

我有两个 collection。

第一个Collection

 {  _id:"601d07fece769400012f1280",
   FieldName:"Employee",
   Type:"Chapter" }

第二个Collection

_id : "601d11905617082d7049153a",
SurveyId : "601d118e5617082d70491539",
TemplateName : "",
Elements : [

       {
            _id : "601d07fece769400012f1280",
            FieldName : "Employee",
            Type : "Chapter"
       },

       {
          _id : "601d07fece769400012f1281",
          FieldName : "Contract",
          Type : "Chapter"
       }]

当我进行查找时

        '$lookup': {
          'from': 'SecondCollection', 
          'localField': 'FieldName', 
          'foreignField': 'Elements.FieldName', 
          'as': 'SurveyInfo'
        }

我会得到正确的结果,但我有时会得到“第二Collection匹配管道的 $lookup 阶段的文档总大小超过 16793600 字节”。

所以我改变了我的方法,将第二个 collection 与管道连接起来,所以我只得到了我需要的字段。

 "from": 'SecondCollection',
"let": { "fieldname": "$fieldname" },
"pipeline": [
  { "$match": 
    { "$expr": 
      { "$eq": ["$elements.fieldname", "$$fieldname"] }}},
  { "$project": { "SurveyId": 1}}
],
"as": 'SurveyInfo'

现在的问题是这个 returns 所有第二个 Collection 文件。未返回匹配的文档。

我想得到以下结果

_id:"601d07fece769400012f1280",
FieldName:"Employee",
Type:"Chapter",
SurveyInfo: [
      {
       _id:"601d11905617082d7049153a",
       SurveyId:"601d118e5617082d70491539"
      }
 ]

我无法弄清楚这个问题。请帮助我。

很少修复,

  • 你必须尝试 $in 而不是 $eq 因为 $Elements.FieldName 将 return 字符串数组
  • 需要更正 let$match 条件中的字段名称
db.FirstCollection.aggregate([
  {
    "$lookup": {
      "from": "SecondCollection",
      "let": { "fieldname": "$FieldName" },
      "pipeline": [
        { "$match": { "$expr": { "$in": ["$$fieldname", "$Elements.FieldName"] } } },
        { "$project": { "SurveyId": 1 } }
      ],
      "as": "SurveyInfo"
    }
  }
])

Playground


匹配嵌套条件,你可以试试,

  • $reduce 迭代 Elements.Children.FieldName 嵌套数组的循环,我们将使用 $concatArrays
  • 将嵌套级别数组合并到单个 sting 数组中
db.FirstCollection.aggregate([
  {
    "$lookup": {
      "from": "SecondCollection",
      "let": { "fieldname": "$FieldName" },
      "pipeline": [
        {
          "$match": {
            "$expr": {
              "$in": [
                "$$fieldname",
                {
                  $reduce: {
                    input: "$Elements.Children.FieldName",
                    initialValue: [],
                    in: { $concatArrays: ["$$this", "$$value"] }
                  }
                }
              ]
            }
          }
        },
        { "$project": { "SurveyId": 1 } }
      ],
      "as": "SurveyInfo"
    }
  }
])

Playground