为什么CouchDB Reduce函数必须是可交换的?

时间:2013-11-30 17:29:14

标签: mapreduce couchdb

我刚刚开始搞乱CouchDB。在许多地方,我已经看到它表明CouchDB视图的reduce函数需要是关联的和可交换的(例如,the CouchDB wiki说明这一点)。我确实理解CouchDB可以分阶段进行减少,并通过重新减少来缓存和重用中间结果。我也清楚为什么reduce函数必须是关联的。但是,我不明白交换要求来自何处。

让我试着更清楚一点。假设我有一个map函数,它在我的数据库的所有内容上运行时输出10个值。为简单起见,假设这些值是整数1 - 10(1,2,3,4等)。

假设我有一个函数f(keys, values, rereduce),它是关联的,但不是可交换的。让我们说f忽略键并重新声明参数,并且只对values数组进行操作。因此,我将在其余的解释中省略键并重新减少参数。

据我了解,交换属性需要f([1, 2]) == f([2, 1]),但我不认为CouchDB会这样做。我确实理解它可能会将f之前计算的结果传递给地图输出的一个子集,但我相信它总会按顺序传递给我。例如,我可能会使用rereduce == true来调用f([f([1, 2, 3]), f([4, 5, 6])]),但我认为我的reduce函数不会像f([f([4, 5, 6]), f([1, 2, 3])])那样被调用,也不会以任何其他类似的方式调用参数不是“有序的”。如果这是正确的,那么我就明白为什么我的reduce函数需要是可交换的。

额外说明:

整个问题在上面,但是如果它有助于某人理解我感到困惑的地方,这就是我对关联属性所需要的理解。

对我来说,似乎f是关联意味着:

f([1, 2, 3]) == f([f([1, 2]), 3]) == f([1, f([2, 3])]) == f([f([1]), f([2, 3])]) == f([f([1, 2]), f([3])])

第3个是二元运算符的标准数学关联定义。由于我们正在使用数组和非二元运算符这一事实,最后两个是略微概括。因此,例如,如果CouchDB缓存了减少[1, 2]的结果和减少[3, 4]的结果,它可以使用rereduce == true调用我的reduce函数,只传递f([1, 2])f([3, 4])计算f([1, 2, 3, 4]),而无需我的代码处理所有4项。

应用

对于它的价值,我有一个用例,我的地图输出是排列。由于置换函数是关联的,但不是可交换的,我想我可以使用CouchDB减少缓存来真正有效地做一些很酷的事情。而且,在我的测试中,它似乎有效。但是wiki,CouchDB书和其他消息来源说减少必须是可交换的,因此我不应该这样做。

1 个答案:

答案 0 :(得分:0)

将此内容发布到CouchDB邮件列表和got an answer。目前看来,减少功能需要是可交换的。但是,CouchDB计划集成BigCouch,此时数据将在多个服务器之间进行分片。在该环境中,传递给reduce函数的值可以基本上是随机的,因此需要可交换。

如果只有一个分片,非交换函数将继续正常工作,而CouchDB团队并不认为这将始终有效;他们保留将来改变事物的权利,并且只能承诺如果它是可交换的,你的减少将起作用。