2013-10-30 73 views
3

我正在調整我在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" 
    ] 
} 

我在頂層文件屬性中的一個執行不區分大小寫的搜索和嵌套文件屬性之一:

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

從我有限的蒙戈的知識,這看起來像一個表掃描這就是爲什麼查詢不執行得非常好。但是,我不知道如何使這個查詢更好!我期望我創建的索引覆蓋此查詢,但是,情況肯定不是這樣。

現在,我想指出的最後一件事是,這當然不是最健壯的服務器上。硬件規格(包括CPU和RAM)非常有限。但是,如果我的分析是正確的,而且我正在進行表掃描,那麼我可以在Mongo方面進行一些性能改進。

+2

我可以告訴你這是正則表達式是問題,他們不能使用索引 – Sammaye

+0

@Sammaye - 即使我在兩個正則表達式的開始處刪除通配符,我仍然沒有得到僅索引的查詢(根據「解釋」)。雖然,它看起來像執行時間下降〜6-8秒。我能做出其他更改嗎? –

+0

如果測試or的每個子句會怎麼樣? – Sammaye

回答

0

謝謝大家的回覆。我想跟進這個問題,因爲它有幾張選票,並且確保任何未來在這個頁面上絆倒的人都知道我最終做了什麼。

全文索引聽起來像是一個很好的解決方案。但是,因爲這只是我的一個小項目,所以我不願意在架構上投入更多硬件(全文索引需要400萬條記錄的大量磁盤空間)。

我最終做的是平坦化我的數據結構,使它們更容易查詢刪除了通配符搜索,以便我實際上可以使用該新結構上的索引。通過這樣做,我可以實現indexOnly查詢(雖然性能仍然不是很好,但我發現它足夠我的弱硬件堆棧)。

0

全文索引可能是您需要的。在插入文檔之前,您還可以解析文檔,並將關鍵字放入文檔中的數組中併爲該數組編制索引。