根据数组的所有元素在MongoDB管道中添加聚合字段

bis0qfac  于 2023-02-21  发布在  Go
关注(0)|答案(1)|浏览(117)

给定集合中的以下文档:

[{
  "_id": {
    "$oid": "63f06283b80a395adf27780d"
  },
  "suppliers": [
    {
      "name": "S1",
      "duesPaid": true
    },
    {
      "name": "S2",
      "duesPaid": true
    }
  ]
},{
  "_id": {
    "$oid": "63f06283b80a395adf27780e"
  },
  "suppliers": [
    {
      "name": "S1",
      "duesPaid": true
    },
    {
      "name": "S2",
      "duesPaid": false
    }
  ]
}]

我想在每个文档中创建一个aggregateField,它执行以下操作:如果suppliers数组至少有1个元素,并且其中的每个元素都具有duesPaid field == true,则向文档suppliersPaid = true添加一个字段。否则,添加suppliersPaid = false。管道生成的文档应如下所示:

[{
  "_id": {
    "$oid": "63f06283b80a395adf27780d"
  },
  "suppliers": [
    {
      "name": "S1",
      "duesPaid": true
    },
    {
      "name": "S2",
      "duesPaid": true
    }
  ],
  "suppliersPaid": true,
},{
  "_id": {
    "$oid": "63f06283b80a395adf27780e"
  },
  "suppliers": [
    {
      "name": "S1",
      "duesPaid": true
    },
    {
      "name": "S2",
      "duesPaid": false
    }
  ],
  "suppliersPaid": false,
}]

我已经尝试了以下管道:

[{$addFields: {
  suppliersPaid: {
    $and: [
      { $gte: [{ $size: "$suppliers" }, 1] },
      {
        suppliers: {
          $not: {
            $elemMatch: { duesPaid: false },
          },
        },
      },
    ],
  },
}}]

我得到了以下错误:无效的$addFields::原因:无法识别的表达式"$elemMatch"
我已经尝试消除对$elemMatch的依赖,如文档www.example.com所示:https://www.mongodb.com/docs/manual/reference/operator/query/elemMatch/#single-query-condition as such:

[{$addFields: {
  suppliersPaid: {
    $and: [
      { $gte: [{ $size: "$suppliers" }, 1] },
      {
        suppliers: {
          $not: {
            duesPaid: false
          },
        },
      },
    ],
  },
}}]

但这会产生错误的结果,即两个单据的suppliersPaid都设置为true,这是不正确的。
注意:我希望避免在这段代码中使用任何类型的JS,也就是说,不要使用$where操作符。

u7up0aaq

u7up0aaq1#

对于第二个条件:

  1. $eq-比较 1.1 的结果以返回空数组。
    1.1. $filter-过滤suppliers中包含{ duesPaid: false }的文档。
db.collection.aggregate([
  {
    $addFields: {
      suppliersPaid: {
        $and: [
          {
            $gte: [
              {
                $size: "$suppliers"
              },
              1
            ]
          },
          {
            $eq: [
              {
                $filter: {
                  input: "$suppliers",
                  cond: {
                    $eq: [
                      "$$this.duesPaid",
                      false
                    ]
                  }
                }
              },
              []
            ]
          }
        ]
      }
    }
  }
])

Demo @ Mongo Playground

相关问题