为什么 mongoose 聚合方法 return 不是文档的所有字段?

Why doesn't mongoose aggregate method return all fields of a 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
      }
    ]

我正在执行以下聚合(mongoplayground.net

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

结果如下

    [
      {
        "_id": "624713340a3d2901f2f5a9c0",
        "exercises": [
          {
            "_id": "624713530a3d2901f2f5a9c3",
            "date": "2022-03-24T00:00:00.000Z",
            "description": "Sitting",
            "duration": 60
          },
          {
            "_id": "624713a00a3d2901f2f5a9ca",
            "date": "2022-03-30T00:00:00.000Z",
            "description": "Sitting",
            "duration": 999
          }
        ]
      }
    ]

所以我的第一个问题是为什么 username 字段不包含在结果中?

第二个是为什么 练习 不限制为 1? limit 当前是否应用于整个用户文档?如果是这样,是否可以仅将其应用于练习子文档?

谢谢!

第一个问题

当您使用 $project 阶段时,只会返回您在阶段中指定的属性。您只指定了 exercises 属性,因此只返回那个。注意 _id 属性 默认返回,即使你没有指定它。


第二个问题

$limit也是$project的一个阶段。您可以将 $limit 应用于整个生成的文档数组,而不是应用于一个文档的嵌套数组 属性。


解决方案

$project阶段,也可以指定username字段,所以也会返回。您可以使用 $slice 来指定要从数组 属性.

返回的文档数,而不是 $limit
db.collection.aggregate([
  {
    "$match": {
      "_id": "624713340a3d2901f2f5a9c0"
    }
  },
  {
    "$project": {
      "username": 1,
      "exercises": {
        "$slice": [
          {
            "$filter": {
              "input": "$exercises",
              "as": "exercise",
              "cond": {
                "$eq": [
                  "$$exercise.description",
                  "Sitting"
                ]
              }
            }
          },
          1
        ]
      }
    }
  }
])

Working example