我可以获取与过滤器匹配的子图表的计数吗?

发布于 2025-01-18 21:59:45 字数 1882 浏览 0 评论 0原文

我有以下文档

    [
      {
        "_id": "624713340a3d2901f2f5a9c0",
        "username": "fotis",
        "exercises": [
          {
            "_id": "624713530a3d2901f2f5a9c3",
            "description": "Sitting",
            "duration": 60,
            "date": "2022-03-24T00:00:00.000Z"
          },
          {
            "_id": "6247136a0a3d2901f2f5a9c6",
            "description": "Coding",
            "duration": 999,
            "date": "2022-03-31T00:00:00.000Z"
          },
          {
            "_id": "624713a00a3d2901f2f5a9ca",
            "description": "Sitting",
            "duration": 999,
            "date": "2022-03-30T00:00:00.000Z"
          }
        ],
        "__v": 3
      }
    ]

,我正在尝试通过以下

    db.collection.aggregate([
      {
        "$match": {
          "_id": "624713340a3d2901f2f5a9c0"
        }
      },
      {
        "$project": {
          "username": 1,
          "exercises": {
            "$slice": [
              {
                "$filter": {
                  "input": "$exercises",
                  "as": "exercise",
                  "cond": {
                    "$eq": [
                      "$$exercise.description",
                      "Sitting"
                    ]
                  }
                }
              },
              1
            ]
          },
          "count": {
            "$size": "exercises"
          }
        }
      }
    ])

当我尝试使用练习使用“ $ size”: “练习”,我得到一个错误查询失败:( location17124)无法优化pipeline ::由::引起的::参数to $ size必须是一个数组,但是类型:字符串

但是,当我使用“ $ size”:“ $ ercorepes”访问子记录练习时,我得到了文档中包含的所有子图表的计数。

注意:我知道在此示例中,我使用$ slice,然后将限制设置为1,但是在我的代码中,它是一个变量。

I have the following document

    [
      {
        "_id": "624713340a3d2901f2f5a9c0",
        "username": "fotis",
        "exercises": [
          {
            "_id": "624713530a3d2901f2f5a9c3",
            "description": "Sitting",
            "duration": 60,
            "date": "2022-03-24T00:00:00.000Z"
          },
          {
            "_id": "6247136a0a3d2901f2f5a9c6",
            "description": "Coding",
            "duration": 999,
            "date": "2022-03-31T00:00:00.000Z"
          },
          {
            "_id": "624713a00a3d2901f2f5a9ca",
            "description": "Sitting",
            "duration": 999,
            "date": "2022-03-30T00:00:00.000Z"
          }
        ],
        "__v": 3
      }
    ]

And I am trying to get the count of exercises returned with the following aggregation (I know it is way easier to do it in my code, but I am trying to understand how to use mongodb queries)

    db.collection.aggregate([
      {
        "$match": {
          "_id": "624713340a3d2901f2f5a9c0"
        }
      },
      {
        "$project": {
          "username": 1,
          "exercises": {
            "$slice": [
              {
                "$filter": {
                  "input": "$exercises",
                  "as": "exercise",
                  "cond": {
                    "$eq": [
                      "$exercise.description",
                      "Sitting"
                    ]
                  }
                }
              },
              1
            ]
          },
          "count": {
            "$size": "exercises"
          }
        }
      }
    ])

When I try to access the exercises field using "$size": "exercises", I get an error query failed: (Location17124) Failed to optimize pipeline :: caused by :: The argument to $size must be an array, but was of type: string.

But when I access the subdocument exercises using "$size": "$exercises" I get the count of all the subdocuments contained in the document.

Note: I know that in this example I use $slice and I set the limit to 1, but in my code it is a variable.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

蓝眸 2025-01-25 21:59:46

你实际上走在正确的轨道上。您实际上并不需要$slice。您只需使用 $reduce 即可执行过滤。您的计数不起作用的原因是过滤和 $size 处于同一阶段。在这种情况下,将使用预先过滤的数组来进行计数。您可以通过添加 $addFields 阶段来解决此问题。

db.collection.aggregate([
  {
    "$match": {
      "_id": "624713340a3d2901f2f5a9c0"
    }
  },
  {
    "$project": {
      "username": 1,
      "exercises": {
        "$filter": {
          "input": "$exercises",
          "as": "exercise",
          "cond": {
            "$eq": [
              "$exercise.description",
              "Sitting"
            ]
          }
        }
      }
    }
  },
  {
    "$addFields": {
      "count": {
        $size: "$exercises"
      }
    }
  }
])

这是 Mongo Playground 供您参考。

You are actually on the right track. You don't really need the $slice. You can just use $reduce to perform the filtering. The reason that your count is not working is that the filtering and the $size are in the same stage. In such case, it will take the pre-filtered array to do the count. You can resolve this by adding a $addFields stage.

db.collection.aggregate([
  {
    "$match": {
      "_id": "624713340a3d2901f2f5a9c0"
    }
  },
  {
    "$project": {
      "username": 1,
      "exercises": {
        "$filter": {
          "input": "$exercises",
          "as": "exercise",
          "cond": {
            "$eq": [
              "$exercise.description",
              "Sitting"
            ]
          }
        }
      }
    }
  },
  {
    "$addFields": {
      "count": {
        $size: "$exercises"
      }
    }
  }
])

Here is the Mongo playground for your reference.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文