Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用mongoDB将嵌入文档与父字段进行比较_Mongodb_Mongodb Query_Aggregation Framework - Fatal编程技术网

使用mongoDB将嵌入文档与父字段进行比较

使用mongoDB将嵌入文档与父字段进行比较,mongodb,mongodb-query,aggregation-framework,Mongodb,Mongodb Query,Aggregation Framework,考虑以下集合,其中父文档有一个值为100000的amount字段,并且有一个具有相同字段amount和相同值的嵌入文档数组 { "_id" : ObjectId("5975ce5f05563b6303924914"), "amount" : 100000, "offers" : [ { "amount": 100000 } ] } 是否有任何方法可以将至少有一个嵌入文档offer的所有对象与父对象的金额匹配 例如,如果我对此进行查询,它可以正常工作: find

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

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

是否有任何方法可以将至少有一个嵌入文档
offer
的所有对象与父对象的金额匹配

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

find({ offers: { $elemMatch: { loan_amount: 100000 } } })
但我不知道实际值
100000
在我试图汇编的实际查询中,我需要为父文档金额字段使用一个变量。像这样的

find({ offers: { $elemMatch: { loan_amount: "parent.loan_amount" } } })
谢谢你的建议。我希望用
$eq
$elemMatch
来实现这一点,并避免聚合,但这可能是不可能的

谢谢

标准查询无法“比较”文档中的值。这实际上是您使用
.aggregate()
和:

这里我们使用来比较父文档中的
“amount”
值与数组中的值。如果至少有一个是“相等”的,则我们
“$$KEEP”
文档,否则我们
“$$PRUNE”

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

如果您实际上也只需要“匹配数组元素”,那么您可以在投影中添加一个:

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" ] }
      }
    }
  }}
])
但是,主要原则当然是“减少”返回到的文档数量,仅将实际符合条件的文档作为“第一”优先级。否则,您只是在做不必要的计算和工作,这需要花费时间和资源,以获得稍后将丢弃的结果


因此,首先“过滤”,然后“重塑”作为优先级。

我认为自从MongoDB版本3.6以来,您实际上可以通过使用操作符的简单过滤器来实现这一点

大致如下:

find({
  $expr: {
    $in: [
      "$amount",
      "$offers.amount"
    ]
  }
})

请参见

上的一个实时示例非常感谢,如果提供文档有自己的集合并引用其他文档,会更容易些吗。这种聚合似乎需要做很多工作,我是说性能方面,将报价文档放在它自己的集合中并引用其他文档id是否更好?@stefankono“性能方面”将内容放在另一个集合中更糟糕。成本高昂。这就是为什么您首先“应该”使用MongoDB。没有“简单”的方法将一个字段与另一个字段进行比较。任何方法都有成本,关系数据库也是如此。再次感谢,我将尝试一下。我感谢你的努力,祝你有一个愉快的一天!
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" ] }
      }
    }
  }}
])
find({
  $expr: {
    $in: [
      "$amount",
      "$offers.amount"
    ]
  }
})