【问题标题】:Return whole document from aggregation从聚合中返回整个文档
【发布时间】:2014-01-29 22:49:44
【问题描述】:

我正在使用以下查询来获取数据库中每篇文章的最新评论:

db.comments.aggregate([
    {
        "$match": {
            "post_id": {
                "$in": [ObjectId("52c5ce24dca32d32740c1435"), ObjectId("52c5ce24dca32d32740c15ad")]
            }
        }
     },
     {
         "$sort": {"_id": -1}
     },
     {
        "$group": {
            "_id": "$post_id",
            "lastComment": {
                "$first": "$_id"
            }
        }
     }
])

我希望它返回整个评论的文档,但它只返回每个文档的 _id 字段。那么,将所有最新的 cmets 作为一个完整文档(或至少包含其他一些字段)的正确方法是什么?

【问题讨论】:

  • cmets 是否在文档字段中?您正在选择该组的第一个 _id,但如果您有另一个带有 post cmets 的字段,则应更改“$_id”。也许一个示例文档可以帮助我们。
  • 评论存储在一个单独的集合中,其中每个评论都是一个单独的文档,每个评论都通过“post_id”字段引用相应帖子的文档。如果这回答了你的问题。

标签: mongodb aggregation-framework


【解决方案1】:

目前您无法通过单个 $first 运算符获取整个 comment 文档。但是您可以在$group 步骤中包含其他必要的字段(类似于_id 字段):

{
    "$group": {
        _id: "$post_id",
        lastComment: { "$first": "$_id" },
        field_1: { "$first": "$field_1" },
        field_2: { "$first": "$field_2" },
        // ...
        field_N: { "$first": "$field_N" }
    }
}

根据这张 JIRA 票证:https://jira.mongodb.org/browse/SERVER-5916,整个文档将从 2.5.3 版本 的聚合操作中返回。可以使用新变量:$$ROOT$$CURRENT

{
    "$group": {
        _id: "$post_id",
        lastComment: { "$first": "$$CURRENT" }
    }
}

【讨论】:

  • 这看起来不错,但最终结果不是像 {},{},{} 那样获取 json 对象。我收到 {lastComment:{actualEntireObj}},{lastComment:{actualEntireObj}},{lastComment:{actualEntireObj}}。如何在 MongoDB 中使用 $project(aggregation) 从 lastComment 解包对象并以正常方式 {}、{}、{} 返回?有什么想法吗?
  • 是的,我找到了所需的解决方案,点赞。感谢以上提示..
【解决方案2】:

按照建议,我们可以这样做:

 {
    "$group": {
        _id: "$post_id",
        lastComment: { "$first": "$$CURRENT" }
    }
}

然后在任何 mongodb 服务器 3.4 或更高版本上使用 { '$replaceRoot': { 'newRoot': '$lastComment' } } 将对象从 {lastComment:{actualEntireObj}},{lastComment:{actualEntireObj}} 解包到 @ 987654323@ 这样它将嵌入 $$ROOT 文档到顶层并替换所有其他字段,例如从 $group 聚合阶段返回的 _id

    db.collection.aggregate([
    {
        "$match": {
            "post_id": {
                "$in": [ObjectId("52c5ce24dca32d32740c1435"), ObjectId("52c5ce24dca32d32740c15ad")]
            }
        }
    },
    {
        "$sort": { "_id": -1 }
    },
    {
        "$group": {
            _id: "$post_id",
            lastComment: { "$first": "$$CURRENT" }
        }
    },
    { '$replaceRoot': { 'newRoot': '$lastComment' } }
])

【讨论】:

  • 如果你有多个文档,你可以使用 $push 而不是 $first !!
猜你喜欢
  • 2023-03-26
  • 2021-06-01
  • 2020-08-26
  • 2021-11-16
  • 2019-06-26
  • 2020-04-26
  • 2015-06-24
  • 2013-05-06
  • 2014-05-28
相关资源
最近更新 更多