2012-03-31 12 views
0

$を使用するか、並べ替えを行うとテーブル全体がスキャンされ、タイトルとキーワードに対するインデックスが作成されない$またはクエリを使用するときに2つのインデックスを使用するにはどうすればよいですか?

このクエリは、両方のタイトルやキーワードインデックス

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

Mongoのソートとインデックスは、複雑なトピックです。 Mongoには特別なエラーがあり、項目が多すぎると索引なしで並べ替えができなくなります。したがって、索引付けされていないソートは最終的には失敗し始めるため、索引を尋ねることは良いことです。

あなたの問題をカバーしていると思われるbug in JIRAがありますが、考慮すべきいくつかの詳細があります。

注意すべき最初の事はあなたの最後のクエリです:

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

だけtitle/totaltitleないでインデックス化されているため、これらのクエリは、最終的に失敗します。問題を示すスクリプトがあります。

> 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 
} 

あなたは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のバグのようなものです次のようになります。

あなたとは少し異なりますが、同じ問題が発生します。 title/totalkeyword/totalの両方のインデックスを持っていても、インデックスを最適に使用することはできません。

+0

{total:-1、title:1}のインデックスがあり、{total:-1、title:1}でソートすると、少なくともインデックススキャンをより効率的にすることはできますか? – drogon

+0

@drogon何でフィルタリングしていますか?そこに 'find()'節がありますか? JIRAのバグはソートに '$ or'節を使うことに非常に特有です。 –

関連する問題