【问题标题】:How to get lastest N records of each group in mongodb?如何获取mongodb中每个组的最新N条记录?
【发布时间】:2015-12-17 13:57:07
【问题描述】:

每个城市我都有几个条目。如何获取每个城市的最新3个条目?喜欢:

城市1
记录 1
记录 2
记录 3

城市2
记录 1
记录 2
记录 3

城市3
记录 1
记录 2
记录 3

架构:

var schema = mongoose.Schema({
  city: {type: String},
  title: {type: String},
  created: {type: Number, default: Math.floor(new Date() / 1000)}
})

我试过的代码:

Collection
.find('location $in ' + cities)
.aggregate({$group: {location: "$location"}})
.sort('created: 1')
.limit(3).exec(function(err, docs) { res.render('index', { hash: docs }); });

那么,如何在我应该得到的结果中执行查询:每个城市的 3 个最新标题

【问题讨论】:

  • 它被标记了,但要明确一点:你使用的是猫鼬,对吧?
  • 另外,您要返回一组还是多组?另一个澄清:这些城市中的每一个都是他们自己的收藏品、单独的物品还是什么?
  • 是的,没错!我正在使用猫鼬。
  • 同一个集合。集合 XYZ 和所有这些记录都是它的字段。
  • 酷;可能值得稍微不同的格式。我将添加一个编辑。 :)

标签: node.js mongodb mongoose


【解决方案1】:

mongoDB 3.2 中,您可以使用以下形式的聚合查询来执行此操作:

db.collection.aggregate(
  {$sort: {created: -1}},
  {$group: {_id:'$city', title:{$push: '$title'}},
  {$project: {_id:0, city: '$_id', mostRecentTitle: {$slice: ['$title', 0, 2]}}}
)

使用 mongoDB 3.0 很难做到这一点。在 3.0 中实现这一点有一个非常肮脏的技巧。它涉及几个步骤和其他收集。

首先进行聚合并将结果输出到名为“aggr_out”的临时集合中

查询:

db.collection.aggregate([
  {$sort: {created: -1}},
  {$group: {_id:'$city', title:{$push: '$title'}},
  {$project: {city: '$_id', mostRecentTitle: '$title'}},
  {$out: 'aggr_out'}]
)

使用上面的查询,mostRecentTitle 将拥有从索引 0、1、2、... 排序的所有最近标题.其他标题在应用端可以直接忽略。

如果您不满意,请对输出集合“aggr_out”进行更新,并从该集合中读取数据。查询是,

db.aggr_out.update(
  {},
  {$push: {
    mostRecentTitle: {$each:[], $slice:3}
    }
  }
)

上述操作将对 mostRecentTitle 数组进行切片,使其具有最近的三个标题。阅读此集合以获得您想要的结果。

【讨论】:

  • 我收到此错误“无法识别的管道阶段名称 $project”
  • { [MongoError: exception: invalid operator '$slice'] ..}
  • 如你所说,我的 mongodb 3.0.x 版本没有切片。也许我可以在 slice 上找到其他方法。
  • $slice 有替代品吗?
  • 不,它不是 map-reduce。它是将聚合结果保存到新集合的助手。如果系统中没有足够的内存来完成聚合,它也会有所帮助。见docs.mongodb.org/v3.0/reference/operator/aggregation/out
猜你喜欢
  • 2016-11-26
  • 2022-12-07
  • 1970-01-01
  • 2011-05-24
  • 1970-01-01
  • 1970-01-01
  • 2018-06-14
相关资源
最近更新 更多