我对 CouchDB 的运作方式有些困惑。到目前为止,我已经了解到,第一次请求视图的 map 函数将导致 couchdb 构造一个 b-tree 索引,该索引在以下运行中被引用。
我不确定的是,如果每次请求视图时我的 reduce 函数返回不同的文档,b-tree 是否会重新构建?
谢谢
我对 CouchDB 的运作方式有些困惑。到目前为止,我已经了解到,第一次请求视图的 map 函数将导致 couchdb 构造一个 b-tree 索引,该索引在以下运行中被引用。
我不确定的是,如果每次请求视图时我的 reduce 函数返回不同的文档,b-tree 是否会重新构建?
谢谢
reduce() 函数不返回文档,它返回给定值集的缩减值。map-reduce 的架构如下。为数据库中的每个文档调用 map() 函数。从 map() 你可以 emit() 任意数量的视图行。您可以使用以下代码执行此操作:
emit(key, value);
重要的是要注意 map() 对于每个文档修订仅调用一次,稍后此结果将被缓存。结果只能取决于文档,您不能从请求中传递任何参数或发出随机数。
然后,当您查询视图并定义了 reduce() 函数时,将为与查询键范围匹配的文档发出的所有行调用该函数。同样,无法从请求中传递参数。结果只能取决于传递给 reduce() 函数的值。
在内部,b-tree 结构用于缓存和最小化所需的计算量。您可以使用相同的 map() 函数代码和不同的 reduce() 函数定义多个视图。CouchDB 足够聪明,可以对 map() 的输出进行分片,并且不会多次调用它。
我希望这能澄清一点。祝你好运!
-- 在下面编辑以回答关于在 reduce() 中选择随机行的评论 --
一般来说,在 map() 或 reduce() 中使用 random 是违反 map-reduce 过程的设计的。如果在 map() 或 reduce() 函数中使用随机性,随机结果将被缓存。reduce() 的结果为不同的行子集缓存。您不知道或控制调用reduce() 函数的次数来计算查询的最终结果。如果您执行完全相同的查询两次,第二次甚至可能不需要 1 次调用。
此外,reduce() 函数的设计要求满足以下关系:
reduce(reduce(a) + reduce(b)) = reduce(a + b)
上面的a和b是键值范围。如果您在 reduce 体内使用 random ,这显然不成立。
据我了解,您只想从视图中获取随机行。你为什么不在你的视图中使用一个 reduce="_count" 。您可以在两个查询中执行您的任务:
第一个查询以获取行数
使用reduce=false&skip=random(count)&limit=1的第二个查询以获取视图的随机行。这里随机(计数)是在客户端计算的。