我想我可能正在尝试一些不可能的事情 - 复杂的Couchdb“JOIN”场景

时间:2011-02-10 00:53:08

标签: couchdb mapreduce

我认为我在这里尝试做的事情可能是不可能的,但这值得一试。

我有两种文档类型,OperatorEvent

在下面的示例中,我发出3个键。

[place_id, operator_id, zone_name]

operator_idzone_name是两个文档中的常用字段。这就是我想要在两种文档类型之间进行连接的方式。

我想要取回的是place_id作为第一个emit()的第一个键,以及第二个emit()的Event doc._id

这样,我可以将启动密钥定义为place_id我想要获取Event._id的列表。

function(doc) {
 if(doc.doc_type == 'Operator') {
 for(var i in doc.zones) {
   for(var ii in doc.zones[i].origs) {
     if(doc.zones[i].origs[i])
       emit([doc.zones[i].origs[i], doc._id, doc.zones[i].name], null);
   }
 }
} else if (doc.doc_type == 'Event') {
 for(var i in doc.rates) {
   if(doc.rates[i].zone) {
     emit([0, doc.operator_id, doc.rates[i].zone], doc._id);
   }
 }
}
}

问题是连接不会在第二个emit();

中使用第一个值0

我尝试发出允许连接工作的密钥[operator_id, zone_name],但是reduce()函数需要很长时间并且因为Event._id的列表增长很长而引发错误。

我可能不得不将其分解为两个单独的查询,但希望学习一种我不知道的不同方法。

1 个答案:

答案 0 :(得分:1)

emit()的所有内容均按排序。通常,键是用于获得良好排序顺序的数组:第一个元素具有最高优先级,后跟第二个元素,等等。但是,即使键是一个数组,它仍然是一个整体视图,并且整个视图按该键排序

因此,要在不同文档之间进行连接,它们必须在视图中彼此相邻排序。这意味着他们应该分享emit()密钥的最左边元素。

P.S。使用CouchDB讨论“JOIN”可能没有帮助,尽管人们有时会使用这个词。