在 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] 只会为指定的司机拉车。
干杯。