【问题标题】:Aggregate push N number of array results聚合推送N个数组结果
【发布时间】:2013-07-19 10:00:25
【问题描述】:

我有以下聚合:

db.reports.aggregate({ $group: { _id: "$user", reports: { $push: {report: {properties: "$properties"} } }}}, { $project: { _id: 0, user: "$_id", reports: "$reports"} })

我想以某种方式限制推送到数组中的报告数量。 IE 我想将报告限制为用户定义的值。 1,5,10 等。意思是我希望在报告字段中包含 N 个报告(我将按时间戳排序)。现在我正在推送所有报告,不确定如何限制每个用户的报告数量。

我尝试了 $limit,但这不起作用,因为它限制了返回的用户数量,而不是推送到报告数组中的报告数量。

基本上我想按用户对我的报告进行分组,并且只包含一定数量的报告。我想尽早限制报告的数量,这样我就不必在整个管道中处理整个集合

【问题讨论】:

  • 您可以使用 mapReduce 轻松完成。我不确定您是否可以简单地使用聚合来完成。不幸的是,目前聚合不支持 $slice 运算符。
  • 如果以其他方式聚合每个用户的报告,有没有办法限制数量? IE 如果我没有推入数组。也许在筹备中做几个小组。
  • 不知道有没有可能。但是其他人可能会提出一个想法。同时,你可以试试my reduce来解决你的问题。
  • @innoSPG 感谢您的回复。不幸的是,reduce 有点太慢了,所以我转向聚合。如果我可以用聚合来解决,我可能只需要稍微改变我的数据模型。

标签: mongodb mongoose aggregation-framework


【解决方案1】:

您是否考虑过使用group()?假设您的数据如下所示:

{ "_id" : ObjectId("732"), "user" : "john", "reports" : [  "report1",  "report2",  "report3" ] }
{ "_id" : ObjectId("733"), "user" : "john", "reports" : [  "report4",  "report5",  "report6" ] }
{ "_id" : ObjectId("734"), "user" : "max", "reports" : [  "report1",  "report2",  "report3" ] }
{ "_id" : ObjectId("735"), "user" : "max", "reports" : [  "report4" ] }
{ "_id" : ObjectId("736"), "user" : "eliza", "reports" : [  "report1",  "report2" ] }

假设报告是初始架构中的一个数组,您的聚合调用变为:

var reduce_f = function(curr, result) { 
  result.reports = result.reports.concat(curr.reports); 
}; 

var finalize_f = function(result) { 
  var limit = 5; 
  result.reports = result.reports.slice(0, limit); 
};

db.reports.group({ 
  key: { user: 1 },
  reduce: reduce_f,
  initial: { reports : [] },
  finalize: finalize_f
})

请注意,组将在分片环境中工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-17
    • 1970-01-01
    • 1970-01-01
    • 2022-11-22
    • 1970-01-01
    • 2015-05-07
    • 2022-09-28
    • 1970-01-01
    相关资源
    最近更新 更多