【问题标题】:Mongodb - aggregate by embedded document id overwrite the outer document _idMongodb - 通过嵌入文档 id 聚合覆盖外部文档 _id
【发布时间】:2015-05-08 13:01:38
【问题描述】:

我有这种“评论”模型:

{ _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' }],
}

我想查询所有满足以下条件的 cmets:

  1. sharedToUsers 数组为空
  2. repliedToUsers 数组为空

而且,我希望结果按用户 ID 仅包含每个用户的 1 条评论(最新评论)。

我已尝试创建此聚合(Node.js、猫鼬):

     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});
            }
        });

其实是可以的,但是严重的问题是结果cmets_id字段被嵌套用户_id覆盖了。

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

谢谢

【问题讨论】:

  • 将评论 _id 推送到组结果中,就像您对 user 所做的那样,例如comment_id : { "$first" : "$_id" }.

标签: node.js mongodb mongoose


【解决方案1】:

好的,我有办法。

我只想按 _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!

【讨论】:

    猜你喜欢
    • 2016-12-19
    • 2020-09-18
    • 2020-12-31
    • 2013-09-18
    • 1970-01-01
    • 1970-01-01
    • 2017-07-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多