【问题标题】:MongoDB: Using match with input document variablesMongoDB:使用匹配输入文档变量
【发布时间】:2020-05-22 15:06:30
【问题描述】:

为什么我必须使用此代码:{ $match: { $expr: { <aggregation expression> } } } 来匹配使用文档输入变量的文档而不是:{ $match: { <query> } }

例如:

    $lookup: {
      from: "comments",
      let: { myvar: '$myInputDocVariable'},
      pipeline: [
        { $match:
            { $expr:
               { $and:
                  [
                    { $eq: [ "$varFromCommentDocument",  "$$myvar" ] },
                  ]
               }
            }
         },
        ],
      as: "returnedValue"
    }

上面的查询工作正常,但下面的查询没有按预期工作。为什么是这样?这是否意味着如果您在$lookup 管道中使用输入变量,您必须使用$expr?这是为什么呢?

    $lookup: {
      from: "comments",
      let: { myvar: '$myInputDocVariable'},
      pipeline: [
        { $match: { "$varFromCommentDocument", "$$myvar" } }
      ],
      as: "returnedValue"
    }

【问题讨论】:

    标签: mongodb mongodb-query aggregation-framework


    【解决方案1】:

    这是否意味着如果您在 $lookup 中使用输入变量 管道你必须使用 $expr

    是正确的,默认情况下在过滤器中,即;在.find() 的过滤器部分或$match 聚合阶段,您不能使用文档中的现有字段。

    如果您需要在查询过滤器中使用现有字段的值,那么您需要使用聚合管道,因此为了在 .find()$match 中使用聚合管道,您需要用$expr。使用$match 中的$lookup 过滤器中的let 创建的访问局部变量的相同方法需要由$expr 包装。

    让我们考虑下面的例子:

    示例文档:

    [
      {
        "key": 1,
        "value": 2
      },
      {
        "key": 2,
        "value": 4
      },
      {
        "key": 5,
        "value": 5
      }
    ]
    

    查询:

     db.collection.find({ key: { $gt: 1 }, value: { $gt: 4 } })
    
        Or
    
     db.collection.aggregate([ { $match: { key: { $gt: 1 }, value: { $gt: 4 } } } ])
    

    测试: mongoplayground

    如果您看到上面的查询,输入 14 都被传递到查询中,但是您检查下面的查询,您尝试匹配 key 字段 == value 字段 - 它不起作用:

    db.collection.aggregate([ { $match: { key: { $eq: "$value" } } } ])
    

    测试: mongoplayground

    当您比较两个现有字段时,您不能这样做,因为这意味着您正在检查带有key 字段值作为字符串"$value" 的文档。所以说它不是一个字符串,它实际上是对value 字段的引用,您需要使用$eq 聚合运算符而不是$eq 查询运算符,如下所示:

     db.collection.aggregate([ { $match: { $expr: { $eq: [ "$key", "$value" ] } } } ])
    

    测试: mongoplayground

    【讨论】:

    • 嗨@whoami,请查看其他mongodb aggregation question。谢谢。
    • @YulePale:对不起,伙计,很遗憾,我正在外面度假,此时没有笔记本电脑。
    • 不用担心。感谢您的回复。
    【解决方案2】:

    当您为$lookup 运算符执行uncorrelated sub-queries 时:

    • 如果您需要在pipeline 中比较父集合的field,MongoDB 无法为variable / Aggregation expressions 应用标准查询语法(field:value)。在这种情况下,您需要使用$expr 运算符。

    例子:

    { $match:
      { $expr:
        { $and:[
          { $eq: [ "$varFromCommentDocument",  "$$myvar" ] },
        ]}
      }
    }
    
    • 如果它与“硬编码”值匹配,则无需使用 $expr 运算符。

    例子:

    $lookup: {
      from: "comments",
      pipeline: [
        { $match:{ 
          "key": "value",
          "key2": "value2"
        }}
      ],
      as: "returnedValue"
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-10-02
      • 2020-01-16
      • 2021-02-25
      • 2020-06-28
      • 1970-01-01
      • 2020-06-11
      • 2020-06-18
      • 1970-01-01
      相关资源
      最近更新 更多