使用$进行排序或阻止在mongodb中使用索引?

时间:2012-03-31 02:34:31

标签: mongodb

似乎使用$或者使用sort进行全表扫描并避免使用标题和关键字上的索引如何在使用$或查询时使用我的两个索引?

此查询同时使用标题和关键字索引

db.tasks.find({$or: [{keywords: /^japan/}, {title:/^japan/}]})

这是一个全表扫描并使用我的索引total_-1

db.tasks.find({$or: [{keywords: /^japan/}, {title:/^japan/}]}).sort({total:-1})

虽然针对关键字或带有排序的标题的查询分别使用关键字或标题上的索引。

db.tasks.find({title:/^japan/}).sort({total:-1})
db.tasks.find({keywords:/^japan/}).sort({total:-1})

1 个答案:

答案 0 :(得分:1)

Mongo中的排序和索引是一个复杂的主题。 Mongo还有一个特殊错误,如果您有太多项目,则会阻止您在没有索引的情况下进行排序。因此,您询问索引是件好事,因为未编制索引的排序最终会失败。

bug in JIRA似乎可以解决您的问题,但需要考虑一些额外的细节。

首先要注意的是你上次的查询:

db.tasks.find({title:/^japan/}).sort({total:-1})
db.tasks.find({keywords:/^japan/}).sort({total:-1})

这些查询最终会失败,因为您只是title上的索引而不是title/total上的索引。这是一个可以演示问题的脚本。

> db.foo.ensureIndex({title:1})
> for(var i = 0; i < 100; i++) { db.foo.insert({title: 'japan', total: i}); }
> db.foo.count()
100
> db.foo.find({title: 'japan'}).sort({total:-1}).explain()
... uses BTreeCursor title_1
> // Now try with one million items
> for(var i = 0; i < 1000000; i++) { db.foo.insert({title: 'japan', total: i}); }
> db.foo.find({title: 'japan'}).sort({total:-1}).explain()
Sat Mar 31 05:57:41 uncaught exception: error: {
        "$err" : "too much data for sort() with no index.  add an index or specify a smaller limit",
        "code" : 10128
}

因此,如果您打算查询&amp;在titletotal上排序,然后您需要按顺序对两者进行索引:

> db.foo.ensureIndex({title:1,total:1})
> db.foo.find({title: 'japan'}).sort({total:-1}).explain()
{
        "cursor" : "BtreeCursor title_1_total_1 reverse",
...

我上面列出的JIRA错误类似于以下内容:

> db.foo.find({$or: [title:/^japan/, title:/^korea/]}).sort({total:-1})

你的略有不同,但会遇到同样的问题。即使您在title/totalkeyword/total上都有索引,MongoDB也无法以最佳方式使用索引。