【问题标题】:Add to collection one document that is one field's accumulation in MongoDB将一个文档添加到集合中,该文档是 MongoDB 中一个字段的累积
【发布时间】:2018-08-09 19:05:01
【问题描述】:

如何向集合中添加一个在 MongoDB 中累积值集合字段的文档?

我有一个 MongoDB 集合,其中包含以下格式的文档:

{
  "_id" : 3876435465554,
  "title" : "xxx",
  "category" : "xxx",
  ...
}

所以期望的结果是:

{ "_id" : "All", "num" : 28 }  // <- This is the document that I want include in the output
{ "_id" : "xxx", "num" : 11 }
{ "_id" : "yyy", "num" : 8 }
{ "_id" : "zzz", "num" : 9 }

到目前为止,我已经尝试过:

db.collection.aggregate([
  { $project: { title:1, category:1} },
  { $group: {
      _id: { _id:"$category"},
      num: { $sum: 1 }
    } },
  { $project: { _id:"$_id._id", num:1} },
  { $sort: { _id:1} }
])

但这只会产生文档没有“全部”文档

{ "_id" : "xxx", "num" : 11 }
{ "_id" : "yyy", "num" : 8 }
{ "_id" : "zzz", "num" : 9 }

我不知道如何将“全部”文档与所有“num”值的总和相加。

注意:将 2 次调用链接到 aggregates 我能够在程序中获得期望的输出,但我们的想法是只使用一个 aggregate 来获得输出。

【问题讨论】:

    标签: mongodb mongodb-query aggregation-framework


    【解决方案1】:

    您可以在 3.4 中使用以下聚合查询。

    更改包括添加额外的$group 以计算总计数,同时将单个计数行推入数组,然后$concatArrays 将总行文档添加到单个计数数组。

    $unwind 返回平面结构并按 _id 和 $replaceRoot 排序以将所有文档提升到顶层。

    db.collection.aggregate([
      {"$project":{"title":1,"category":1}},
      {"$group":{"_id":{"_id":"$category"},"num":{"$sum":1}}},
      {"$group":{
        "_id":null,
        "total":{"$sum":"$num"},
        "rest":{"$push":{"num":"$num","_id":"$_id._id"}}
      }},
      {"$project":{"data":{"$concatArrays":[[{"_id":"all","num":"$total"}],"$rest"]}}},
      {"$unwind":"$data"},
      {"$sort":{"data._id":1}},
      {"$replaceRoot":{"newRoot":"$data"}}
    ])
    

    【讨论】:

    • 第二个"total":{"$sum":"$num"}不应该是$group吗?
    • @Alex Blex 是的。谢谢。更正。看来你也错过了:)
    • @Veeram,不,我正在使用构面并行分组,所以在两个管道中应该是 $sum:1
    【解决方案2】:

    您可以使用$facets“链接”数据库端的管道,因此它将是来自客户端的单个请求:

    db.collection.aggregate([
      { $match: { category: { $ne: 'all' } } },
      { $project: { title:1, category:1 } },
      { $facet: {
          total: [ 
            { $group: {
              _id: 'all', 
              num: { $sum: 1 }
             } },
          ],
          categories: [   
            { $group: {
              _id: "$category",
              num: { $sum: 1 }
             } },
          ]
      } },
      { $project: { all: { $concatArrays: [ "$total", "$categories" ] } } },
      { $unwind: "$all" },
      { $replaceRoot: { newRoot: "$all" } },  
      { $sort: { _id:1 } }
    ])
    

    【讨论】:

    • 谢谢@AlexBlex,我也试试你的解决方案。
    猜你喜欢
    • 2015-05-03
    • 1970-01-01
    • 2020-03-21
    • 2011-12-04
    • 2021-04-23
    • 1970-01-01
    • 2016-09-22
    • 2015-01-18
    相关资源
    最近更新 更多