首页 文章

Mongodb - 通过嵌入式文档ID聚合覆盖外部文档_id

提问于
浏览
2

我有这种'评论'模型:

{ _id: <comment-id>,
  user: {
    id: { type: Schema.ObjectId, ref: 'User', required: true },
    name: String
  },
  sharedToUsers:          [{ type: Schema.ObjectId, ref: 'User' }],
  repliedToUsers:         [{ type: Schema.ObjectId, ref: 'User' }],
}

我想查询通过以下条件的所有注释:

  • sharedToUsers数组为空

  • repliedToUsers数组为空

但是,我希望结果只包含用户ID的每个用户的1条评论(最新评论) .

我试图创建这个聚合(Node.js,mongoose):

Comment.aggregate(
        { $match: { "sharedToUsers": [], "repliedToUsers": [] } },
        {
            $group: {
                _id: "$user.id",
                user: { $first: "$user" },
            }
        },
        function (err, result) {
            console.log(result);
            if (!err) {
                res.send(result);
            } else {
                res.status(500).send({err: err});
            }
        });

它确实有效,但严重的问题是结果注释_id字段被嵌套用户_id覆盖 .

如何保持聚合工作但不覆盖原始注释_id字段?

谢谢

1 回答

  • 3

    好的,我有一个解决方案 .

    我想要的只是按_id进行分组,但是返回结果文档的_id字段(使用$ group运算符时会被覆盖) .

    我做的就像wdberkley说的,我添加了comment_id:{“$ first”:“$ _id”}然后我不想返回comment_id字段(因为它不适合我的模型)所以我创建了一个$ project,它将comment_id放在常规的_id字段中 .

    这基本上是它的样子:

    Comment.aggregate(
            {
                $match: {
                    "sharedToUsers": [], "repliedToUsers": []
                }
            },
            {
                $group: {
                    comment_id: { $last: "$_id" },
                    _id: "$user.id",
                    content: { $last: "$content" },
                    urlId: { $last: "$urlId" },
                    user: { $last: "$user" }
                }
            },
            {
                $project: {
                    _id: "$comment_id",
                    content: "$content",
                    urlId: "$urlId",
                    user: "$user"
                }
            },
            { $skip: parsedFromIndex },
            { $limit: (parsedNumOfComments - parsedFromIndex) },
            function (err, result) {
                console.log(result);
                if (!err) {
                    Comment.populate(result, { path: "urlId"}, function(err, comments) {
                       if (!err) {
                           res.send(comments);
                       } else {
                           res.status(500).send({err: err});
                       }
                    });
                } else {
                    res.status(500).send({err: err});
                }
            });
    

    谢谢wdbkerkley!

相关问题