猫鼬聚合$ group与嵌套对象

时间:2020-02-28 02:12:25

标签: mongodb object mongoose grouping aggregation

我有以下解析器:

        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'并返回它,但返回以下错误不能正常工作:

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

有人知道我在做什么错吗?

1 个答案:

答案 0 :(得分:2)

$group只能包含_id$first$last$sum等累加器对象。在您的情况下,您的建筑物嵌套对象和该语法是不允许-累加器必须处于最高级别。您可以尝试两种方法,一种是从$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",
                ...
            }
        }
    }
}