使用MongoDB跨多个集合进行基于范围的按时间顺序分页查询?

时间:2013-08-27 21:32:56

标签: node.js mongodb pagination mongoose

是否有一种有效的方法可以跨多个集合执行基于范围的查询,并按时间戳索引进行排序?我基本上需要从3个集合中提取最新的30个文档,显而易见的方法是查询每个集合中最新的30个文档,然后过滤并合并结果。然而,这效率有点低。

即使我只选择查询中的时间戳字段,然后对最新的30个文档进行第二批查询,我不确定这是一个更好的方法。这将是每个分页请求的90个文档(整个或单个字段)。

基本上,客户可以订阅文章,每个文章类别相差0到2个字段。我刚刚选择了3,因为这是用户在测试版中到目前为止订阅的文章的平均数量。由于存在可能的字段差异,我认为将所有不同类型的文章放在一个集合中并不是非常一致。

3 个答案:

答案 0 :(得分:2)

如果您的查询确实是根据选择的类别获取最新文章,那么我建议您:

A)将所有文档存储在单个集合中,以便他们可以利用单个查询来获取组合分页结果。除非您在集合中具有非常一致的日期范围,否则您需要跟踪日期范围和计数,以便您可以合理地获取可以合并的一组文档。一个集合中的30可能比另一个集合中的所有集合更旧。您可以为时间戳和类别添加索引,然后限制结果。

B)积极缓存所有内容,以便您很少需要进行合并

答案 1 :(得分:1)

MongoDB操作一次只能运行一个集合。因此,您需要使用符合查询需求的集合来构建架构。

选项A:从支持集合中获取ID,加载完整文档,在内存中排序

因此,您需要拥有一个集合,将3个集合的ID,主集合名称和时间戳组合到一个集合中,然后查询以获取30个ID /集合对,然后加载相应的完整文档有3个额外的查询(每个主要集合1个),当然记住这些查询不会以正确的组合顺序返回,因此您需要在将结果页面的内容中手动排序,然后再将其返回给客户端。

{
  _id: ObjectId,
  updated: Date,
  type: String
}

这种方式允许mongo为你做分页。

选项B:3个查询,联合,排序,限制

或者如您所说,从每个集合中加载30个文档,对内存中的并集进行排序,删除额外的60,然后返回组合结果。这避免了额外的收集开销和同步维护。

所以我认为你当前的方法(我称之为选项B)是那两个不那么好的选择中的较小者。

答案 2 :(得分:0)

你可以使用我在这里解释的相同想法,虽然这篇文章与MongoDB文本搜索相关,它适用于任何类型的查询

MongoDB Index optimization when using text-search in the aggregation framework

我们的想法是查询按日期和ID排序的所有集合,然后对结果进行排序/混合以返回第一页。通过使用上一页中的最后一个文档的日期和ID来检索后续页面。