2013-01-23 32 views
2

這個問題是關於如何在MongoDB中使用索引來查找嵌套文檔中的某些內容,而無需索引每個單獨的子級別。 我在MongoDB中收集「測試」基本上是這樣的:mongodb:爲嵌套文檔創建一個頂級索引,而不必索引每個單獨的子級別?

{ 
"_id" : ObjectId("50fdd7d71d41c82875a5b6c1"), 
"othercol" : "bladiebla", 
"scenario" : { 
     "1" : { [1,2,3] }, 
     "2" : { [4,5,6] } 
}} 

方案有多個按鍵,每個文檔都可以擁有的情景(即從無到一個子集全部)任何子集。另外:場景不能是一個數組,因爲我需要它作爲Python中的字典。我在「場景」字段中創建了一個索引。
我的問題是,我想選擇集合,篩選具有特定值的文檔。所以這個工作很好功能:

db.test.find({"scenario.1": {$exists: true}}) 

但是,它不會使用任何我已經放在場景的指數。只有當我在「scenario.1」上使用索引時纔會使用索引。但是我可以有數千個(或更多)的場景(而且這個場景本身有100000個記錄),所以我不想!
所以我嘗試選擇:

db.test.find({"scenario": "1"}) 

這將使用情況的指數,但不會返回結果。製作數組的場景仍然會給出相同的索引問題。

我的問題清楚了嗎?任何人都可以給我一個關於如何在這裏實現最佳性能的指針?

P.s.我已經看到了這一點:How to Create a nested index in MongoDB?但這種解決方案是不可能在我的情況(由於場景的量)把一個index on a subobjectscenario在這種情況下沒用,因爲當你在一個完整的濾波它只會被用來

回答

2

約翰尼香港的答案是一個很好的解釋答案,應在一般情況下使用。如果您需要有很多場景並且不需要複雜的查詢,我只是建議您解決您的問題的一種解決方法。不要將值保留在場景字段中,只需在該字段下面保存場景的ID,並將值保留爲文檔中的另一個字段,並使用場景ID作爲此字段的關鍵字。

例子:

{ 
"_id" : ObjectId("50fdd7d71d41c82875a5b6c1"), 
"othercol" : "bladiebla", 
"scenario" : [ "1", "2"], 
"scenario_1": [1,2,3], 
"scenario_2": [4,5,6] 
}} 

有了這個模式,你可以使用場景索引來查找特定的場景。但是,如果您需要查詢特定場景值,則需要在每個場景值字段(例如scenario_1,scenario_2等)上再次有一個索引。如果您需要爲每個字段創建索引,則不要更改原始模式併爲每個嵌套字段使用稀疏索引,這可能有助於減小索引的大小。

+0

謝謝你cubbuk!在我的具體用例中,我不需要對基礎值進行過濾,只需檢索它們(在將文檔寫入mongodb之前,所有null和0值都已經過預過濾)。 我明白scenario_1解決方案的好處(使檢索效率更高),但是我的具體使用案例也需要比較,所以實際上很高興有這樣的數據:) 所以,我要做一些混搭:如你所描述的那樣添加場景數組+將保持嵌套的字典與python中的一樣。性能上的一些冗餘名稱:)謝謝! – Carst

+0

不客氣=) – cubbuk

3

scenario對象而不是單個字段(將其視爲二進制blob比較)。

你要麼需要在每個可能的領域("scenario.1""sceanario.2"等)添加一個索引或返工您的模式做這樣的事情來擺脫動態密鑰的:

{ 
"_id" : ObjectId("50fdd7d71d41c82875a5b6c1"), 
"othercol" : "bladiebla", 
"scenario" : [ 
    { id: "1", value: [1,2,3] }, 
    { id: "2", value: [4,5,6] } 
}} 

然後您可以將單個索引添加到scenario.id以支持您需要執行的查詢。

我知道你說你需要scenario是一個字典,而不是一個數組,但我不明白你有多少選擇。

+0

謝謝!非常有見地! – Carst

+0

(我只能接受一個答案不幸,但這個解釋也真的幫助我!) – Carst

相關問題