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

问题描述 投票:0回答:1

给定集合中的以下文档:

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

我想在每个文档中创建一个执行以下操作的聚合字段:如果

suppliers
数组至少有 1 个元素,并且其中的每个元素都有
duesPaid == 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' 导致

我试图根据文档

https://www.mongodb.com/docs/manual/reference/operator/query/elemMatch/#single-query-condition
消除对$elemMatch的依赖:

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

但这会产生将两个文档的

suppliersPaid
设置为 true 的错误结果,这是不正确的。

注意:我想避免在这段代码中使用任何类型的 JS,即没有

$where
运算符。

mongodb aggregation-framework
1个回答
1
投票

对于第二个条件:

  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
                    ]
                  }
                }
              },
              []
            ]
          }
        ]
      }
    }
  }
])

演示@Mongo Playground

© www.soinside.com 2019 - 2024. All rights reserved.