首页 > 解决方案 > 数组上的MongoDB $expr

问题描述

蒙古数据库:4.0.13

我在理解和使用数组时遇到了麻烦。

让我们使用以下文档开始并创建一个新集合(dbRepeatElement):

db.testRepeatElement.insert([
{
    "data" : {
        "FlsResSemires_2" : {
            "Sospensione" : [
                {
                    "DataInizio" : 1548806400000,
                    "DataFine" : 1549065600000,
                    "Motivazione" : "1"
                }
            ]
        }
    },
    "derived" : {
        "DATAFINEANNORIFERIMENTO" : 1609372800000,
        "regione190" : "190",
        "REGAOEROG" : "190209820300",
        "REGASLEROG" : "190209"
    }
}    
])

在更大的聚合中,以下部分不起作用:

db.testRepeatElement.aggregate([
    {
        $match: {
             $expr: {
                 $gt: ["$data.FlsResSemires_2.Sospensione.DataInizio", "$derived.DATAFINEANNORIFERIMENTO"]
             }
        }
    }

])

结果:返回匹配项(错误!只需检查日期)

阅读 mongodb 文档似乎是,结合使用数组、聚合和 $expr 不会返回预期结果,您必须指定要检查的数组元素,例如:

db.testRepeatElement.aggregate([
    {
        $match: {
             $expr: {
                 $gt: ["$data.FlsResSemires_2.0.Sospensione.DataInizio", "$derived.DATAFINEANNORIFERIMENTO"]
             }
        }
    }

])

结果:返回不匹配(正确!)

问题:我的要求是检查数组中的每个元素,那么如何在不使用 $unwind 的情况下解决这个问题?为什么会有这样的结果?

标签: mongodbaggregation-framework

解决方案


$filter聚合运算符用于对数组元素进行匹配操作以下聚合查询将仅生成与条件Sospensione匹配的数组元素$gt

db.testRepeatElement.aggregate( [
{
  $addFields: {
      "data.FlsResSemires_2.Sospensione": {
          $filter: {
              input: "$data.FlsResSemires_2.Sospensione",
              cond: {
                $gt: [ "$$this.DataInizio", "$derived.DATAFINEANNORIFERIMENTO" ]
              }
          }
      }
  }
},
{
   $match: { 
       $expr: {
            $gt: [ { $size: "$data.FlsResSemires_2.Sospensione" }, 0 ]
       }
   }
}
] ).pretty()

推荐阅读