带有嵌套对象的猫鼬聚合 $group

mongoose aggregation $group with nested object

我有以下解析器:

        const result = await UserPassage.aggregate([
      { $sort: { createdAt: -1 } },
      {
        $group: {
          _id: '$level',
          level: { $first: '$level' },
          passageId: { $first: '$passageId' },
          userId: { $first: '$userId' },
          type: { $first: '$type' },
          category: { $first: '$category' },
          score: { $first: '$score' },
          completedStage: { $first: '$completedStage' },
          userPassageStatsId: {
            _id: { $first: '$_id' },
            stats: {
              readingTime: { $first: '$readingTime' },
              qtdVocab: { $first: '$qtdVocab' },
              qtdTestDone: { $first: '$qtdTestDone' },
              totalQuiz: { $first: '$totalQuiz' },
              progress: { $first: '$progress' },
            },
          },
        },
      },
      { $sort: { level: 1 } },
    ]);

    await UserPassageStats.populate(result, { path: 'userPassageStatsId' });

问题是我需要填充 'userPassageStatsId' 和 return 但它运行不正常 return 出现以下错误:

 MongoError: The field 'userPassageStatsId' must be an accumulator object

有谁知道我做错了什么吗?

$group 只能包含 _id 或累加器对象,例如 $first$last$sum 等。在您的情况下,您的建筑嵌套对象和那个不允许语法 - 累加器必须位于顶层。您可以尝试两种方法,要么 return 来自 $group 的平面结构,然后使用 $project:

进行整形
{
    $group: {
        _id: '$level',
        level: { $first: '$level' },
        passageId: { $first: '$passageId' },
        userId: { $first: '$userId' },
        type: { $first: '$type' },
        category: { $first: '$category' },
        score: { $first: '$score' },
        completedStage: { $first: '$completedStage' },
        userPassageStatsId_id: { $first: '$_id' },
        readingTime: { $first: '$readingTime' },
        qtdVocab: { $first: '$qtdVocab' },
        qtdTestDone: { $first: '$qtdTestDone' },
        totalQuiz: { $first: '$totalQuiz' },
        progress: { $first: '$progress' }
    }
},
{
    $project: {
        _id: 1,
        level: 1,
        ...,
        userPassageStatsId: {
            _id: "$userPassageStatsId_id",
            stats: {
                readingTime: "$readingTime",
                ...
            }
        }
    }
}

或使用 $$ROOT 为每个组捕获第一个对象并使用 $project:

重塑它
{
    $group: {
        _id: '$level',
        d: { $first: "$$ROOT" }
    }
},
{
    $project: {
        _id: 1,
        level: "$d.level",
        ...,
        userPassageStatsId: {
            _id: "$d._id",
            stats: {
                readingTime: "$d.readingTime",
                ...
            }
        }
    }
}