Rob*_*ell 6 couchdb foreign-keys
让我举一个简单的例子:你有一个订单和一个购物车.我设想坚持这一点的一种方法是保存订单文档和购物车文档.订单文档可以有一个名为"shopping-cart"的字段,其值是相关Cart文档的UUID.我可以想象的另一种方法是使用"shopping-cart"字段保存Order文档,该字段包含整个Cart的关联数组.换句话说,我没有将Cart明确地保存为独立文档,而是将Cart文档嵌入Order文档中.
如果我们稍后决定购物车应该是持久性的,那么返回的用户会发现他的半成品购物车在会议期间等待他?我想我们可以将这两种方法结合起来,在购物车不完整时将其分开,并在最终确定/购买时将其嵌入订单文件中.
虽然我担心CouchDB没有外键约束,但这两种方法都可行.在第一种方法中,Cart文档可能会被删除,从而使您的数据集损坏.
你如何决定使用哪种方法?这些方法中的一种对CouchDB来说更具惯用性吗?有没有我错过的方法?
我是CouchDB的新手,所以我很难看到具有或多或少标准化结构的优点/缺点.
另一方面,如果它们不是一对一的,那么使用复杂的键,您可以使用视图排序规则来进行连接。
function(doc) {
if (doc.type == 'order') {
emit([doc.cartid, 1], doc);
} else if (doc.type == 'cart') {
emit([doc.id, 0], doc);
}
}
Run Code Online (Sandbox Code Playgroud)
该文档将由 cartid 与购物车后的订单进行核对。您的应用程序代码可以轻松加入此流,并且您可以使用 startkey 和 endkey 按特定的 cartid 进行查询。
排序规则请参见:查看排序规则。
您还可以使用reduce 将它们连接在一起。
只需将地图功能更改为:
function(doc) {
if (doc.type == 'order') {
emit([doc.cartid, 1], {cartid: doc.cartid, orders: [doc]});
} else if (doc.type == 'cart') {
emit([doc.id, 0], {cartid: doc.id, orders: [], cart: doc);
}
}
Run Code Online (Sandbox Code Playgroud)
并添加一个像这样的reduce函数:
function(keys, values) {
var out = {cartid: null, orders: [], cart: null};
for (idx in values) {
var doc = values[idx];
out['cartid'] = doc.cartid;
if (doc.cart) { out['cart'] = doc.cart };
for (idx2 in doc.orders) {
out.orders.push(doc.orders[idx2]);
}
}
return out;
}
Run Code Online (Sandbox Code Playgroud)
这将为每个购物车返回一个文档,其中包含一个 cartid、一组订单文档和一个购物车文档。
如果上面的代码中有错误,我深表歉意,但我没有方便的 couchdb 测试实例来尝试它们。不过,您应该了解总体思路,CouchDB wiki 有更多详细信息。