使用mongoDB将嵌入式文档与父字段进行比较 [英] Compare embedded document to parent field with mongoDB

查看:144
本文介绍了使用mongoDB将嵌入式文档与父字段进行比较的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑以下集合,其中父文档具有值为100000amount字段,并且存在具有相同字段amount和相同值的嵌入式文档数组.

Consider the following collection, where the parent document has a amount field with the value 100000 and there's an embedded array of documents with the same field amount and the same value.

{
"_id" : ObjectId("5975ce5f05563b6303924914"),
"amount" : 100000,
"offers" : [ 
    {
        "amount": 100000
    }
]

}

有什么方法可以匹配具有至少一个嵌入式文档offer且与父对象具有相同数量的所有对象?

Is there any way to match all objects that has at least one embedded document offer with the same amount as the parent?

例如,如果我对此进行查询,它就可以正常工作:

If I for example query this, it works just fine:

find({ offers: { $elemMatch: { loan_amount: 100000 } } })

但是我不知道我要组装的实际查询中的实际值100000,我需要为父文档数量字段使用一个变量.像这样的东西.

But I don't know the actual value 100000 in the real query I'm trying to assemble, I would need to use a variable for the parent documents amount field. Something like this.

find({ offers: { $elemMatch: { loan_amount: "parent.loan_amount" } } })

感谢您的任何建议.我希望使用$eq$elemMatch进行此操作,并避免发生聚集,但这也许是不可能的.

Thankful for any suggestions. I was hoping to do this with $eq or $elemMatch, and to avoid aggregates, but maybe it's not possible.

谢谢!

推荐答案

标准查询无法比较"文档中的值.这实际上是您使用.aggregate() $redact :

Standard queries cannot "compare" values in documents. This is actually something you do using .aggregate() and $redact:

db.collection.aggregate([
  { "$redact": {
    "$cond": {
      "if": {
        "$gt": [
          { "$size": {
            "$filter": {
              "input": "$offers",
              "as": "o",
              "cond": { "$eq": [ "$$o.amount", "$amount" ] }
            }
          }},
          0
        ]
      },
      "then": "$$KEEP",
      "else": "$$PRUNE"
    }
  }}
])

在这里,我们使用 $filter 进行比较父文档中"amount"的值与数组中的值相同.如果至少一个等于",则我们"$$KEEP"该文档,否则我们"$$PRUNE"

Here we use $filter to compare the values of "amount" in the parent document to those within the array. If at least one is "equal" then we "$$KEEP" the document, otherwise we "$$PRUNE"

在最新版本中,我们可以使用 .

In most recent versions, we can shorten that using $indexOfArray.

db.collection.aggregate([
  { "$redact": {
    "$cond": {
      "if": {
        "$ne": [
          { "$indexOfArray": [ "$offers.amount", "$amount" ] },
          -1
        ]
      },
      "then": "$$KEEP",
      "else": "$$PRUNE"
    }
  }}
])

如果您实际上也只想要匹配数组元素",则可以添加

If you actually only wanted the "matching array element(s)" as well, then you would add a $filter in projection:

db.collection.aggregate([
  { "$redact": {
    "$cond": {
      "if": {
        "$gt": [
          { "$size": {
            "$filter": {
              "input": "$offers",
              "as": "o",
              "cond": { "$eq": [ "$$o.amount", "$amount" ] }
            }
          }},
          0
        ]
      },
      "then": "$$KEEP",
      "else": "$$PRUNE"
    }
  }},
  { "$project": {
    "amount": 1,
    "offers": {
      "$filter": {
        "input": "$offers",
        "as": "o",
        "cond": { "$eq": [ "$$o.amount", "$amount" ] }
      }
    }
  }}
])

但是主要原则当然是减少"返回给的那些文档的数量,这些文档实际上是符合条件的第一"优先级.否则,您只是在进行不必要的计算而浪费时间和资源,因为以后您将放弃这些结果.

But the main principle is of course to "reduce" the number of documents returned to only those that actually match the condition as a "first" priority. Otherwise you are just doing unnecessary calculations and work that is taking time and resources, for results that you later would discard.

因此优先考虑过滤",然后优先考虑重塑".

So "filter" first, and "reshape" second as a priority.

这篇关于使用mongoDB将嵌入式文档与父字段进行比较的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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