如何使用聚合计算特定文档的总和?

时间:2015-11-05 19:33:14

标签: mongodb mongoose mongodb-query aggregation-framework

我有一个表示消息线程的模式。因此,mongo数据库中的每个文档都类似于:

{
    id: "thread_id",
    participants: ["user1", "user2"],
    unReadMessageCounts: [
         {
             participant: "user1",
             count: 5
         },
         {
             participant: "user2",
             count: 3
         }
}

我想要做的是获取给定用户的所有未读消息计数的总和 - 比如“user2”。我知道我可以通过在集合上执行find()然后编写一个函数来总结给定用户的计数来做到这一点。但是如果可能的话,我想使用mongo的aggregate功能。我知道我可以做一个match来首先选择“user2”是参与者的所有线程,但是我如何构造group和/或sum表达式来拉出文件中的正确字段?

1 个答案:

答案 0 :(得分:2)

使用以下聚合管道获取所需结果。初始步骤会将传入的文档过滤为仅通过 $match 运算符接受#test { background-image: url("background2.jpg"); height: 100px; /* or whatever */ } 参与者。

然后,前面的管道阶段通过 $unwind 运算符“非规范化”df$date = as.POSIXct(df$date,format="%Y-%m-%d") df$year = as.numeric(format(df$date,format="%Y")) df$month = as.numeric(format(df$date,format="%m")) years = unique(df$year) # initialize a new data frame to store in your summed values newdf=NULL # run through a loop starting at your second year and ending at second last for(i in 2:(length(years)-1)){ #data from year1 start = df[df$year==years[i] & df$month %in% c(10,11,12),] end = df[df$year==years[i+1] & df$month %in% c(1,2),] data1 = rbind(start,end) # in case you have NAs in your data you can add ra.rm = T sum.data = sum(data1$temp,na.rm = T) df1 = as.data.frame(list(Year = years[i], sum.data = sum.data)) # or paste year 1 and year 2 together #df1 = as.data.frame(list(Year = paste(years[i],years[i+1],sep="-"), # sum.data = sum.data)) newdf = rbind(newdf,df1) } head(newdf) 数组,该运算符为每个现有文档输出数组中的2个文档(在上面的示例数据中) )。

需要进一步过滤以汇总正确参与者的数据,这是通过另一个 $match 管道步骤完成的。

使用 $group 的最终聚合操作指定"user2"的{​​{1}}组,使用累加器运算符计算管道中所有文档的总计数< unReadMessageCounts字段上的strong> $sum

因此,在给定的样本数据上运行此聚合管道:

_id

将产生结果:

null