MongoDB 表达嵌套整数列表计数的过滤结果

MongoDB Express filter results on count of nested list of ints

我是 mongoDB 的新手,所以在根据需要过滤我的 collection 时遇到了一些困难。

我有这个collection

[
  {
    "id": "sdfsdfsdf",
    "key": "tryrtyrty",
    "createdAt": "2017-01-28T01:22:14.398Z",
    "counts": [
      170
    ],
    "value": "Something"
  },
  {
    "id": "hjmhjhjm",
    "key": "yuiyuiyui",
    "createdAt": "2017-01-28T01:22:14.398Z",
    "counts": [
      150,
      160
    ],
    "value": "Something"
  }
]

我想按日期范围(min-max 日期)和计数范围进行过滤,这意味着我想为 field 中总和的总计数提供最小值和最大值。例如,我想过滤最小计数和为 200 且最大为 400 的结果。这只会 return 第二个结果(总和为 310,而第一个结果总和为 170)。

现在我有这个:

db.collection.aggregate([
  {
    $project: {
      totalCount: {
        $sum: {
          "$filter": {
            "input": "$counts",
            "as": "bla",
            "cond": {
              "$gte": [
                "$sum", // I think the error is here, I dont know how to reference the sum of the list
                300 //I want records whose count sum is more than this value
              ]
            }
          }
        }
      }
    }
  }
])

这 return 是 0 上带有 TotalCount 的所有记录,这不是我想要的,我希望记录与计数条件匹配并具有正确的 TotalCount(并且最终也匹配日期)

[
  {
    "_id": ObjectId("5a934e000102030405000000"),
    "totalCount": 0
  },
  {
    "_id": ObjectId("5a934e000102030405000001"),
    "totalCount": 0
  }

期望的输出

[
  {
    "_id": ObjectId("5a934e000102030405000001"),
    "totalCount": 310,
    "key": "yuiyuiyui",
    "createdAt": "2017-01-28T01:22:14.398Z"
  }
]

如有任何帮助,我们将不胜感激。如果它同时带有日期和计数过滤器,则更多。

您不应该使用 $filter,因为它不适合这种情况。

阶段:

  1. set - 使用 $sum 数组中 counts 的所有元素创建 totalCounts
  2. $match - 过滤范围内 totalCounts 的文档。
  3. $unset - 删除装饰输出文档的字段。
db.collection.aggregate([
  {
    $set: {
      "totalCounts": {
        $sum: "$counts"
      }
    }
  },
  {
    $match: {
      totalCounts: {
        $gte: 200,
        $lte: 400
      }
    }
  },
  {
    $unset: [
      "counts",
      "id"
    ]
  }
])

Sample Mongo Playground


对于日期范围过滤器,您需要 $expr$and 运算符,如下所示

{
  $match: {
    totalCounts: {
      $gte: 200,
      $lte: 400
    },
    $expr: {
      $and: [
        {
          $gte: [
            {
              "$toDate": "$createdAt"
            },
            /* Date from */
          ]
        },
        {
          $lte: [
            {
              "$toDate": "$createdAt"
            },
            /* Date to */
          ]
        }
      ]
    }
  }
}

Sample Mongo Playground (with date range filter)