MongoDB:使用匹配输入文档变量 [英] MongoDB: Using match with input document variables

查看:9
本文介绍了MongoDB:使用匹配输入文档变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么我一定要使用这个代码:{ $match: { $expr: { <aggregation expression>} } } 使用文档输入变量匹配文档,而不是执行: { $match: { <query>} } ?

例如:

 $lookup: {来自:评论",让:{ myvar:'$myInputDocVariable'},管道:[{ $匹配:{ $expr:{ $ 和:[{ $eq: [ "$varFromCommentDocument", "$$myvar" ] },]}}},],如:返回值"}

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

 $lookup: {来自:评论",让:{ myvar:'$myInputDocVariable'},管道:[{ $match: { "$varFromCommentDocument", "$$myvar" } }],如:返回值"}

解决方案

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

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

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

让我们考虑下面的例子:

示例文档:

<预><代码>[{关键":1,价值":2},{关键":2,价值":4},{关键":5,价值":5}]

查询:

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

测试: mongoplayground

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

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

测试: mongoplayground

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

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

测试: mongoplayground

Why do I have to use this code: { $match: { $expr: { <aggregation expression> } } } to match a document using a document input variable as opposed to doing: { $match: { <query> } } ?

For example:

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

The query above works fine but the query below does not work as expected. Why is this? Does this mean that if you are using input variables in a $lookup pipeline you have to use $expr? why is that?

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

解决方案

Does this mean that if you are using input variables in a $lookup pipeline you have to use $expr

Yes correct, by default in filters i.e; in filter part of .find() or in $match aggregation stage you can't use an existing field in the document.

If at all if you need to use existing field's value in your query filter then you need to use aggregation pipeline, So in order to use aggregation pipeline in .find() or in $match you need to wrap your filter query with $expr. Same way to access local variables got created using let of $lookup filter in $match needs to be wrapped by $expr.

Let's consider below example :

Sample Docs :

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

Query :

 db.collection.find({ key: { $gt: 1 }, value: { $gt: 4 } })

    Or

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

Test : mongoplayground

If you see the above query both input 1 & 4 are passed into query but it you check below query where you try to match key field == value field - it doesn't work :

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

Test : mongoplayground

Above as you're comparing two existing fields then you can't do that as it mean you're checking for docs with key field value as string "$value". So to say it's not a string it's actually a reference to value field you need to use $eq aggregation operator rather than $eq query operator like below :

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

Test : mongoplayground

这篇关于MongoDB:使用匹配输入文档变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆