使用索引字段从集合中选择一组随机项(MongoDB)

时间:2014-07-17 18:57:38

标签: mongodb sorting random indexing skip

我正在使用MongoDB 2.4.10,我有一个包含四百万条记录的集合,以及一个创建不超过50000个子集的查询,即使对于我们的超级用户也是如此。我需要从该子集中随机选择30个项目,并且考虑到跳过和限制的潜在性能问题(特别是当使用1-50000的随机跳过量进行30次时),我偶然发现了以下解决方案:

  • 为每个记录创建一个完全随机数的字段
  • 在此字段上创建索引
  • 按字段排序,并使用skip(X).limit(30)获取30个项目的页面,虽然在随机字段方面是连续的,但实际上彼此之间没有任何关系。对于用户来说,它们似乎是随机的。

我的索引如下:

{a: 1, b: 1, c: 1, d: 1}

我还有一个单独的索引:

{d : 1}

'd'是随机区域。

我的查询如下:

db.content.find({a : {$in : ["xyz", "abc"]}, b : "ok", c : "Image"})
.sort({d : 1}).skip(X).limit(30)

当集合很小时,这很有效。但是,在我们的性能和实时系统上,此查询失败,因为它不使用a,b,c,d索引,而是仅使用此索引:

{d : 1}

因此,查询最终扫描的记录超过了所需的记录(按25倍)。所以,我介绍了提示:

db.content.find({a : {$in : ["xyz", "abc"]}, b : "ok", c : "Image"})
.hint({a : 1, b : 1, c : 1, d : 1}).sort({d : 1}).skip(X).limit(30)

现在,对于X的所有值,最高可达11000,并且explain()显示正在使用的正确索引。但是,当跳过量超过11000时,我得到:

{
    "$err" : "too much data for sort() with no index.  add an index or specify a smaller limit",
    "code" : 10128
}

据推测,遇到此错误的风险是查询(没有提示)之前未使用此索引的原因。所以:

  1. 为什么Mongo认为排序没有索引可以使用,当我强制它使用最后明确包含排序字段的索引时?
  2. 有更好的方法吗?

0 个答案:

没有答案