2010-08-05 50 views
3

我開始研究map-reduce數據庫。如何在map-reduce數據庫中實現引用,例如CouchDB或MongoDB?例如,假設我有司機和汽車,並且我想標記某個司機駕駛一輛汽車。在SQL是這樣的:如何在map-reduce數據庫中實現引用?

SELECT person_id, car_id FROM driver, car WHERE driver.car = car.car_id 

(也就是說,如果我沒記錯的權利 - 我還沒有在SQL編程一會兒)

在具有參考語言是以往更簡單:一個Person的實例可以指向Car的實例。

什麼是map-reduce等價於這種關係?

回答

2

在CouchDB中,您可以編寫一個map/reduce,輸出所有汽車和帶有複雜鍵的驅動程序,然後使用鍵範圍來選擇兩者。例如,假設你的文件看起來像這兩個...

{ 
    "_id": "...", 
    "_rev": "...", 
    "docType": "driver" 
} 

{ 
    "_id": "...", 
    "_rev": "...", 
    "docType": "car", 
    "driver": "driver's _id" 
} 

你可以使用duck typing,而不是指定的DOCTYPE,但我喜歡這種方法更好。

您的地圖功能:

function(doc) 
{ 
    if(doc.docType == "driver") 
    emit([doc.id, 0], doc); 
    elseif(doc.docType == "car") 
    emit([doc.driver, 1], doc]; 
} 

我們複雜的組合鍵是一個數組,其中第一項始終是司機_id。陣列中的第二項防止關鍵碰撞,並允許我們直接引用汽車或駕駛員(稍後會詳細介紹)。

我們現在可以使用鍵範圍查詢參數來獲取這兩個文檔。 。

?startkey=["driver _id"]&endkey=["driver _id", {}] 

這基本上說「給我與司機_id作爲第一個項目,以及任何在第二任陣列這工作,因爲對象 - endkey的數組中的第二個項目 - 被分類爲最高。請參閱http://wiki.apache.org/couchdb/View_collation?redirect=ViewCollation#Collation_Specification瞭解有關物品如何在鍵中排序/稱重的更多信息:

這也可以很好地縮放,因爲我們可以在地圖函數中添加更多信息,而無需更改客戶端中的查詢。贊助者docType:我們只需爲docType字段添加另一個elseif,然後再添加emit([doc.driver, 2], doc);。現在我們可以在一個請求中提取所有三個文檔來自上面的相同鍵範圍查詢。

當然,您也可以指定單個文檔而不是全部拖動它們。 ?key=["driver's _id", 1]會爲指定的駕駛員拉車。

乾杯。

1

在文檔數據庫中,可以將相關對象嵌入到擁有對象的文檔中,例如,該驅動程序文檔還包含屬於該驅動程序的所有汽車。這是文檔數據庫的強大功能;它們允許您輕鬆存儲非規範化數據。

{ 
    "_id": "joe_the_driver", 
    "name": "Joe", 
    "cars": [ 
    { "_id": "123-AB", /* car properties */ }, 
    { "_id": "456-YZ", /* car properties */ } 
    ] 
} 

此格式僅適用於一對多關係。如果司機和汽車之間的關係是多到很多,你必須創建查找文件:

{ 
    "_id": "joe_the_driver", 
    "car_ids": [ /* ID's that refer to car documents */ ] 
} 

{ 
    "_id": "123-AB", 
    "driver_ids": [ /* ID's that refer to driver documents */ ] 
} 

需要注意的是大多數文檔的數據庫都沒有辦法執行文檔之間關係很重要以SQL數據庫的方式工作。您的應用程序負責執行和維護這些關係。