チャット ルームからのフォローアップを要約すると、この問題は実際には find() クエリに関連しており、約 50 万件のドキュメントすべてをスキャンして 15 件を検索しています。
db.tweet_data.find({
$or:
[
{ in_reply_to_screen_name: /^kunalnayyar$/i, handle: /^kaleycuoco$/i, id: { $gt: 0 } },
{ in_reply_to_screen_name: /^kaleycuoco$/i, handle: /^kunalnayyar$/i, id: { $gt: 0 } }
],
in_reply_to_status_id_str: { $ne: null }
} ).explain()
{
"cursor" : "BtreeCursor id_1",
"nscanned" : 523248,
"nscannedObjects" : 523248,
"n" : 15,
"millis" : 23682,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : false,
"indexOnly" : false,
"indexBounds" : {
"id" : [
[
0,
1.7976931348623157e+308
]
]
}
}
このクエリは、大文字と小文字を区別しない正規表現を使用しているため、インデックスを効率的に使用できません (この場合、実際には定義されていませんでしたが)。
推奨されるアプローチ:
検索用に小文字handle_lc
とフィールドを作成するinreply_lc
それらに複合インデックスを追加します。
db.tweet.ensureIndex({handle_lc:1, inreply_lc:1})
複合インデックスの順序により、すべてのツイートhandle
を ( ) または ( handle,in_reply_to
)で効率的に検索できます。
正規表現の代わりに完全一致で検索:
db.tweet_data.find({
$or:
[
{ in_reply_to_screen_name:'kunalnayyar', handle:'kaleycuoco', id: { $gt: 0 } },
{ in_reply_to_screen_name:'kaleycuoco', handle:'kunalnayyar', id: { $gt: 0 } }
],
})