2013-04-22 105 views
0

我有以下格式在MongoDB中收集數據:MongoDB的嵌入文檔索引問題

{ 
    _id: ObjectId, 
    Product: string, 
    Modules: [ 
     { 
      StaticModuleId: Int64, 
      Set: [ 
       { 
        k: Int64, 
        v: { 
         Value: Double, 
         AnotherId: Int64 


      } 
      }, 
      ... 
     ] 
    }, 
    ... 
] 

}

這裏是我的命名MyIndex指數:

{ 
    Product: 1, 
    'Modules.StaticModuleId': 1, 
    'Modules.Set.k': 1, 
    'Modules.Set.v.Value': 1 
} 

在收集5文檔,每個文檔有10個模塊和100個元素,每個集合中共有50個模塊和5000個條目。然後我跑這個查詢:

{ 
    'Product': 'Test', 
    $and: [ 
     { 
      'Modules.StaticModuleId': 2010220, 
      'Modules.Set': { 
       $elemMatch: { 
        k: 41439, 
        'v.Value': 2186233 
       } 
      } 
     }, 
     { 
      'Modules.StaticModuleId': 2010226 
     }, 
     { 
      'Modules.StaticModuleId': 2010228 
     } 
    ] 
} 

這裏是.explain():

{ 
    cursor: 'BtreeCursor MyIndex', 
    isMultiKey: true, 
    n: 4, 
    nscannedObjects: 941, 
    nscanned: 941, 
    nscannedObjectsAllPlans: 941, 
    nscannedAllPlans: 941, 
    scanAndOrder: false, 
    indexOnly: false, 
    nYields: 0, 
    nChunkSkips: 0, 
    millis: 52 
} 

至於我繼續添加額外的$ elemMatch子句中的性能降低到> 200毫秒。這種類型的查詢是否可索引,如果有的話,有關我如何提高性能的想法?

+0

爲什麼你有$和表達呢?爲什麼不列舉用','分隔的所有條件? – 2013-04-23 03:53:19

+0

我認爲在嘗試在一個元素內部索引時會出現問題,請參閱http://stackoverflow.com/questions/10207448/mongodb-indexes-for-elemmatch IMO,您可能需要考慮讓您的模塊成爲第一類公民。 – Fatmuemoo 2013-04-23 04:50:25

回答

1

嘗試刪除以前的索引,並與多鍵標誌像這樣創建:

db.collection.ensureIndex({{'Product':1, 'Modules.StaticModuleId':1, 'Modules.Set':1, 'Modules.Set.k':1, 'Modules.Set.v.Value':1}, {multikey:true}) 
在我的測試情況下

,我只有100 scaned對象和米利斯= 0

提示:您可以加載數據和/或索引到存儲器通過:使用下一個腳本來重現問題和數據準備

db.runCommand({ touch: "collection", data: true, index: true }) 

我':

for(var prod=0; prod<1000; prod++) { 
    prodObj={Product:"product" + prod}; 
    modObj=[]; 
    for(var mod=0; mod < 10; mod++) { 
     seObj=[]; 
     for(var se=0; se < 100; se++) { 
      seObj[se] = {k: "Int64-" + se, v:{Value:"Double-" + se}, AnotherId:"Int64"}; 
     } 
     modObj[mod]={StaticModuleId:"Int64-"+prod, Set:seObj}; 
    } 
    prodObj.Modules=modObj; 
    db.so.insert(prodObj); 
} 

可能是你任務

+0

我用'Modules.Set'創建了一個索引:1,它沒有問題。 – 2013-04-24 19:03:16

0

我認爲數據模型不是那麼好,這是一個不正確的。這是一種像模特這樣的關係。如果你能像這樣改變數據模型,以簡單:

{ 
    Product: "string", 
    StaticModuleId: "string", 
    Set: 
    [ 
    { 
     k: "string", 
     v: 
     { 
     Value: "double", 
     AnotherId: "string" 
     } 
    } 
    ] 
} 

你將有一個更良好的性能和更低的複雜性