2014-06-30 69 views
1

我是MongoDB的新手,在執行解決方案時遇到困難。 考慮在那裏我有兩個集合的情況下:在客戶端和銷售收取這樣的設計MongoDB的分析查詢

Client 
========== 
id 
full name 
mobile 
gender 
region 
emp_status 
occupation 
religion 

Sales 
=========== 
id 
client_id //this would be a DBRef 
trans_date //date time value 
products //an array of collections of product sold in the form {product_code, description, units, unit price, amount} 
total sales 

現在有開發另一個收集分析查詢的要求,其中以下問題都可以回答

  1. 按性別,地區和emp_status的銷售分佈情況如何?
  2. 什麼是在特定地區的客戶主要購買產品?

我考慮實現一個非常規範化的集合來創建銷售和客戶端集合的屬性的平坦和廣泛集合,以便我可以使用map-reduce來進一步回答問題。 在關係型數據庫管理系統中,通過連接返回的聚合將回答這些問題,但我對如何使Map-Reduce或Agregation幫助失去了幫助。

問題: 如何實現Map-Reduce以映射2個集合? 是否可以鏈接MapReduce操作?

問候。

回答

2

MongoDB不會做JOINs - 期!

MapReduce總是運行在一個集合上。你不能有一個從多個集合中選擇的MapReduce作業。這同樣適用於聚合。

當您想要進行一些數據挖掘(而不是MongoDBs最強套裝)時,您可以創建一個非規格化的所有Sales集合以及嵌入的對應Client對象。你將不得不寫一個小程序或腳本,在所有客戶端進行迭代,並且

  1. 查找所有Sales文件的客戶爲例
  2. 合併來自Client相關領域到每個文件
  3. 插入所得到的文檔進新的集合

當你Client文件小,並且不經常改變,你可能會考慮到總是將其嵌入到電子書ach Sales。這意味着你將擁有冗餘數據,從經驗豐富的RDB老手的角度來看,這看起來非常邪惡。但請記住,MongoDB不是一個關係數據庫,因此您不應該應用未反映的所有RDBMS教條。數據庫規範化的「無冗餘」規則只有在JOIN相對便宜且無痛時纔可行,而MongoDB則不是這種情況。此外,有時您可能需要冗餘來確保數據持久性。當你想知道你所在地區銷售的歷史發展情況時,你想知道客戶購買產品時居住的地區,而不是現在居住的地區。當每個Sale僅引用當前的Client文檔時,該信息將丟失。當然,你可以通過單獨的Address文件解決這個問題,這些文件有日期範圍,但這會使它更加複雜。

另一種選擇是在每個Client中嵌入Sales的數組。但是,MongoDB不喜歡隨着時間推移而增長的文檔,所以當你的客戶傾向於經常返回時,這可能導致低於標準的寫入性能。

+0

謝謝菲利普,我贊成反規範化策略,並且聚合更簡單。 – okmich