MongoDb聚合3个字段的计数/总和

时间:2017-08-15 18:38:28

标签: mongodb aggregation-framework nosql

我试图获取用户喜欢,分享或评论的内容总和。

我的内容模型具有以下结构。

Content = {
  _id: ObjectId(),
  author: ObjectId(),
  value: <string of post content>
  tags: [<trings>],
  likes: [array of user ids],
  shares: [array of user ids],
  comments: [{
     ContentId( of the same schema ),
     User Id
  }]
}

现在,id喜欢聚合内容文档, 得到这样的结果。

{
   likes: 20,
   shares: 10,
   comments: 5
}

因此,简而言之,只要有内容, 用户ID在likes数组中, 喜欢增加1。

同样的股票和评论。

我不确定聚合框架是否可行。 我想不是,但也许有些mongodb大师知道更好

快速编辑。部分基于提交的第一篇文章,我做了这个。 现在,它似乎工作,但我确定有一些问题,我很遗憾,因为它似乎太简单了:))

db.getCollection('contents').aggregate( [


{$facet: {
      "likes": [
         {$match: {likes: ObjectId("596537d6b63edc2318ee9f0c")} },
         {$group: {
           _id : "$likes",
           count: { $sum: 1 }
         }},
         { $project: { count: 1} }
      ],
      "shares": [
         {$match: {shares: ObjectId("596537d6b63edc2318ee9f0c")} },
         {$group: {
           _id : "$shares",
           count: { $sum: 1 }
         }},
         { $project: { count: 1} }
      ],
      "posts": [
         {$match: {$and: [
             {user: ObjectId("596537d6b63edc2318ee9f0c")},
             {parent: {$exists: false} }
         ]} },
         {$group: {
           _id : "$_id",
           count: { $sum: 1 }
         }},
         { $project: { count: 1} }
      ]
  }
}]);

您能否发现上述代码有问题?

2 个答案:

答案 0 :(得分:0)

db.collection.aggregate( [
  {
    $facet: {
      "LikeCategory": [
        { $unwind: "$likes" },
        { $group : {
           _id : "$likes",
           count: { $sum: 1 }
         }
        },{ $project : {
          userId : "$_id"
           _id : 0,
            count : 1

        }}
      ],
      "ShareCategory": [
        { $unwind: "$shares" },
        { $group : {
           _id : "$shares",
           count: { $sum: 1 }
         }
        },{ $project : {
          userId : "$_id"
           _id : 0,
            count : 1

        }}
      ],
      "CommentCategory": [
        { $unwind: "$comments" },
        { $group : {
           _id : "$comments.userId",
           count: { $sum: 1 }
         }
        },{ $project : {
          userId : "$_id"
           _id : 0,
            count : 1

        }}
      ]
}
}
];

通过这种方式,您将能够找到计数。上面的代码可能有一些语法问题,但我希望你能够解决你的问题。

答案 1 :(得分:0)

您可以在3.4版本中尝试以下聚合。

以下查询将$group所有文档,并使用$in运算符检查输入user_id是否在数组中。

对于likesshares数组,如果找到1则使用user_id其他设置0$sum以汇总所有comments文档。

对于$group,它是两步过程,因为它是数组数组。

user_id逐步查看内容文档中的user_id,并检查每个元素中的输入1,如果匹配则输出0,否则comments

[[1, 0], [1], [1]]在群组阶段后会有数组值comments的数组。下一步是使用$reduce运算符对所有值求和以获得db.collection_name.aggregate([ { "$group": { "_id": null, "likes": { "$sum": { "$cond": [ { "$in": [ user_id, "$likes" ] }, 1, 0 ] } }, "shares": { "$sum": { "$cond": [ { "$in": [ user_id, "$shares" ] }, 1, 0 ] } }, "comments": { "$push": { "$map": { "input": "$comments", "as": "comment", "in": { "$cond": [ { "$in": [ user_id, "$$comment.user_id" ] }, 1, 0 ] } } } } } }, { "$addFields": { "comments": { "$reduce": { "input": "$comments", "initialValue": 0, "in": { "$add": [ "$$value", { "$sum": "$$this" } ] } } } } } ]) 计数。

var timepicker = new Pikaday({
field: document.getElementById('datepicker'),
firstDay: 1,
minDate: new Date(2016, 0, 1),
maxDate: new Date(2100, 12, 31),
yearRange: [2016,2100],
showTime: true,
autoClose: false,
use24hour: false,
format: 'YYYY-MM-dd'