【问题标题】:Why do CouchDB Reduce Functions have to be Commutative?为什么 CouchDB Reduce 函数必须是可交换的?
【发布时间】:2013-12-16 16:31:58
【问题描述】:

我刚刚开始使用 CouchDB。在很多地方,我看到它声明 CouchDB 视图的 reduce 函数需要同时具有关联性和可交换性(例如,the CouchDB wiki 就是这样说的)。我确实了解 CouchDB 可以分阶段进行 reduce 并通过 re-reduce 缓存和重用中间结果。我也很清楚为什么 reduce 函数必须是关联的。但是,我不明白交换要求的来源。

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

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

据我了解,交换属性需要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] 的结果,它可以调用我的 reduce 函数,使用 rereduce == true,只传递 f([1, 2])f([3, 4]) 来计算 @987654336 @,不需要我的代码处理所有 4 个项目。

应用程序

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

【问题讨论】:

    标签: mapreduce couchdb


    【解决方案1】:

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

    虽然如果只有一个分片,非交换函数将继续正常工作,但 CouchDB 团队并不承诺这将永远有效;他们保留在未来改变事物的权利,并且只能保证你的 reduce 是可交换的。

    【讨论】:

      猜你喜欢
      • 2018-03-24
      • 2018-03-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-01
      • 1970-01-01
      • 2021-12-31
      • 1970-01-01
      相关资源
      最近更新 更多