我开始研究 map-reduce 数据库。如何在 map-reduce 数据库(例如 CouchDB 或 MongoDB)中实现引用?例如,假设我有司机和汽车,我想标记某个司机驾驶汽车。在 SQL 中是这样的:
SELECT person_id, car_id FROM driver, car WHERE driver.car = car.car_id
(也就是说,如果我没记错的话——我已经有一段时间没有用 SQL 编程了。)
在具有引用的语言中,它变得更加简单:Person 的实例可以指向 Car 的实例。
这种关系对应的 map-reduce 是什么?
最佳答案
在 CouchDB 中,您将编写一个 map/reduce 输出所有具有复杂键的汽车和司机,然后使用键范围来选择两者。例如,假设您的文档看起来像这两个...
{
"_id": "...",
"_rev": "...",
"docType": "driver"
}
{
"_id": "...",
"_rev": "...",
"docType": "car",
"driver": "driver's _id"
}
你可以使用 duck typing而不是指定 docType,但我更喜欢这种方法。
您的 map 功能:
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。
这也可以很好地扩展,因为我们可以在 map 函数中添加更多信息,而无需更改客户端中的查询。假设我们添加了一个赞助商 docType:我们只是为 docType 字段添加另一个 elseif
,然后 emit([doc.driver, 2], doc);
。现在我们可以使用上面相同的键范围查询在一个请求中提取所有三个文档。
当然,您也可以指定单个文档,而不是全部拉取。 ?key=["driver's _id", 1]
将为指定的司机拉车。
干杯。
关于mongodb - 如何在 map-reduce 数据库中实现引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3413278/