Mongo で使用している文字列検索クエリを微調整しようとしています。SQL Server の世界では、インデックスがどのように機能し、適切なインデックスを作成するかについて十分に理解していると思います。Mongo でやってみましたが、間違っているとは思いません。
私のコレクションには、およそ 430 万のドキュメントがあります。ドキュメント構造は次のようになります。
{
"_id":{
"$oid":"527027456239d1212c07a621"
},
"ReleaseId":2451,
"Status":"Accepted",
"Title":"Hard Rhythmic Motions",
"Country":"US",
"MasterId":"35976",
"Images":[
{
"Type":"primary",
"URI":"http://api.discogs.com/image/R-2451-1117047026.jpg",
"URI150":"http://api.discogs.com/image/R-150-2451-1117047026.jpg",
"Height":307,
"Width":307
},
{
"Type":"secondary",
"URI":"http://api.discogs.com/image/R-2451-1117047033.jpg",
"URI150":"http://api.discogs.com/image/R-150-2451-1117047033.jpg",
"Height":307,
"Width":307
}
],
"Artists":[
{
"_id":2894,
"Name":"DJ Hyperactive"
}
],
"Formats":[
{
"Name":null,
"Quantity":1
}
],
"Genres":[
"Electronic"
],
"Styles":[
"Hardcore",
"Acid"
]
}
トップレベルのドキュメント プロパティの 1 つと、ネストされたドキュメント プロパティの 1 つに対して、大文字と小文字を区別しない検索を実行しています。
db.releases.find({$or: [{Title: new RegExp('.*mozart.*',"i")},{'Artists.Name': new RegExp('.*mozart.*',"i")}]})
インデックスを作成してみました。実行する.getIndexes()
と、作成したインデックスが表示されます。
{
"v" : 1,
"key" : {
"Title" : 1,
"Artists.Name" : 1
},
"ns" : "discogs.releases",
"name" : "Title_1_Artists.Name_1"
}
この時点で、私はすべての準備ができていると思っていました。ただし、クエリの実行には 28 ~ 32 秒かかります。.explain()
もう少し洞察を得るために電話してみました:
{
"cursor" : "BasicCursor",
"isMultiKey" : false,
"n" : 4098,
"nscannedObjects" : 4292400,
"nscanned" : 4292400,
"nscannedObjectsAllPlans" : 4292400,
"nscannedAllPlans" : 4292400,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 29,
"nChunkSkips" : 0,
"millis" : 29958,
"indexBounds" : {
},
"server" : "lambic:27017"
}
Mongo に関する私の限られた知識からすると、これはテーブル スキャンのように見えます。これが、クエリがうまく機能していない理由です。しかし、このクエリを改善する方法がわかりません! 私が作成したインデックスがこのクエリをカバーすることを期待していますが、そうではないはずです。
さて、最後に指摘したいのは、これは確かに最も堅牢なサーバー上ではないということです. ハードウェアの仕様 (CPU と RAM を含む) は非常に限られています。ただし、分析が正しく、テーブル スキャンを実行している場合、Mongo 側でパフォーマンスを改善できるはずです。