如何在mongodb中获取每个组的最新N条记录?

Fer*_*ili 6 mongoose mongodb node.js

每个城市我都有几个条目。如何获取每个城市的最新 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)}
})
Run Code Online (Sandbox Code Playgroud)

我试过的代码:

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

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

Sar*_*air 6

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]}}}
)
Run Code Online (Sandbox Code Playgroud)

使用 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'}]
)
Run Code Online (Sandbox Code Playgroud)

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

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

db.aggr_out.update(
  {},
  {$push: {
    mostRecentTitle: {$each:[], $slice:3}
    }
  }
)
Run Code Online (Sandbox Code Playgroud)

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