【问题标题】:$match in $lookup pipeline always returns all the documents, not filtering$lookup 管道中的 $match 始终返回所有文档,而不是过滤
【发布时间】:2021-04-09 11:35:01
【问题描述】:

我有两个收藏。

第一次收藏

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

第二次合集

_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'
        }

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

所以我改变了方法,将第二个集合加入管道,所以我只得到了我需要的字段。

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

现在的问题是这会返回所有 SecondCollection 文档。不返回匹配的文档。

我想得到以下结果

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

我无法找出问题所在。请帮帮我。

【问题讨论】:

  • 将第一个字符更改为大写字母,总是给出空结果。
  • 尝试 $in 而不是 $eq 并更正您的字段名称 elements.fieldname 驼峰式大小写和 fieldname 并查看工作 playground
  • "... 现在的问题是这会返回所有 SecondCollection 文档。不返回匹配的文档..." 您可能需要在以下投影中过滤数组.
  • @turivishal 还有一个问题,当我想对 Elements 数组中的子元素应用过滤器时,它失败了。请查看更新后的游乐场mongoplayground.net/p/68KeLN72nz0
  • 你能解释一下你在做什么过滤吗,你只选择了一个字段SurveyId

标签: mongodb mongodb-query aggregation-framework mongodb-compass


【解决方案1】:

一些修复,

  • 您必须尝试$in 而不是$eq,因为$Elements.FieldName 将返回字符串数组
  • 需要更正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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-01
    • 2020-12-29
    • 1970-01-01
    • 2019-02-19
    相关资源
    最近更新 更多