2012-08-22 18 views
3

好,MongoDB的專家,請看看我的收藏:MongoDB:通過索引加速聚合或找到不同的解決方案?

[{ 
    "_id" : "item_0", 
    "Name" : "Item 0", 
    "Description" : "Some description for this item...", 
    "Properties" : { 
    "a" : 5.0, 
    "b" : 0.0, 
    "c" : 6.0, 
    "d" : 6.0, 
    "e" : 2.0, 
    "f" : 0.0, 
    "g" : 9.0, 
    "h" : 3.0, 
    "i" : 4.0, 
    "j" : 5.0 
    } 
}, 
{ // 5.000-10.000 more items... } 
] 

我使用該聚合乘以一組選定的屬性(在這種情況下,b,c和d),到再排序他們通過自己的產品:

{ 
    "aggregate": "item", 
    "pipeline": [ 
     { 
      "$project": { 
       "_id": 1, 
       "Name": 1, 
       "s": { 
        "$multiply": [ 
         "$Properties.a", 
         "$Properties.b", 
         "$Properties.c", 
         "$Properties.d" 
        ] 
       } 
      } 
     }, 
     { 
      "$sort": { 
       "s": -1 
      } 
     }, 
     { 
      "$limit": 100 
     } 
    ] 
} 

現在能正常工作和所有,但是當物品的屬性數量,並增加時間來執行聚集將增加很多!

有沒有更好的辦法(更高效)來實現這樣的事情? 搜索爲最高產品(一組屬性的倍數)必須很快。如果有一種方法來索引這個,所有不同的屬性組合,並讓他們緩存或什麼?索引需要一段時間,只要查詢速度快!

感謝您對此事的任何幫助,我非常感謝!

回答

4

鑑於您對快速搜索和效率的要求,我認爲更好的方法是將Map/Reduce與輸出集合一起使用(至少在聚集框架支持使用集合輸出的時間之前)。

在您的用例中使用輸出集合有幾個優點。

特別是:

  • 你可以有靈活的索引和排序
  • 結果不具備實時計算每個查詢
  • 你沒有被16MB的BSON文件限制尺寸爲直列導致

可以使用merge output option map/reduce的更新您的輸出集合在計算(本質上來說,這將是你的緩存)。

根據您的各種屬性的更新頻率,我將調查基於「最近更新」時間戳或允許你確定何時值需要重新計算一些其他標準漸進的方法。這將允許您隨着收藏的增長保持批量的大小更易於管理。

+0

作爲Sammaye提到的,對於聚合框架開放的功能要求,以支持'$ out'選項,結果保存到輸出集合。請參閱MongoDB問題跟蹤器中的[SERVER-2353](https://jira.mongodb.org/browse/SERVER-3253),以對此功能投票或觀看更新。 – Stennie

+0

的想法是,在用戶每次搜索的時候,他會選擇一些性能上面的例子 - 他們可以改變任何時間(如果別的用戶搜索)。屬性的值不會改變。這仍然可能與地圖/減少。我的意思是,這將需要我爲每個不同的選定屬性組合的結果存儲正確嗎? – Mickel

+0

Hrm ..如果你想從索引結果中選擇,你必須預先計算組合。這對M/R來說是可能的,但根據您的使用情況(即20個屬性中的任何一個,或者總是5個組合),組合的數量可能很難處理。您的要求的問題是,爲了找到匹配,服務器將必須計算所有文檔上的屬性,然後執行內存中排序以找到最前N個結果。既然您的目標是優化速度,我會重新考慮您的模式以及是否有更好的方式來表示數據。 – Stennie

相關問題