为什么默认启用 CouchDB 的 reduce_limit? (在 MapReduce 视图或列表视图中近似 SQL JOINS 更好吗?)
Why is CouchDB's reduce_limit enabled by default? (Is it better to approximate SQL JOINS in MapReduce views or List views?)
我正在使用 CouchDB,我想在查询数据时更好地利用 MapReduce。
我的确切用例如下:
我有很多调查。每个调查都有一个 meterNumber、meterReading 和 meterReadingDate,例如:
{
meterNumber: 1,
meterReading: 2050,
meterReadingDate: 1480000000000
}
然后我使用 Map 函数通过 meterNumber 生成读数。有许多重复的键(在不同日期读取相同的仪表)。即
[
[meterNumber, {reading: xxx, readingDate: xxx}],
[meterNumber, {reading: xxx, readingDate: xxx}],
[meterNumber, {reading: xxx, readingDate: xxx}],
etc
]
然后我在发送到 reduce 函数之前将它们分组,然后 reduce 函数实际上应该扩展值集。 IE。我想要这个:
[
[meterNumber, [{reading:xxx, readingDate: xxx}, {reading:xxx, readingDate: xxx}, {reading:xxx, readingDate: xxx}]],
[meterNumber, [{reading:xxx, readingDate: xxx}, {reading:xxx, readingDate: xxx}, {reading:xxx, readingDate: xxx}]],
[meterNumber, [{reading:xxx, readingDate: xxx}, {reading:xxx, readingDate: xxx}, {reading:xxx, readingDate: xxx}]],
etc
]
为了 运行 CouchDB 上的这个 MapReduce 视图,我必须允许这种类型的结果集 (Couchdb - Is it possible to deactivate the reduce_overflow_error error)。
这表明我可能 运行 遇到大型结果集的性能问题。是这样吗?为什么必须在 CouchDB 上专门启用此设置?
*** 编辑
下面接受的答案向我指出,我在 MapReduce 中所做的事情也可以(并且更好)使用列表。这是关于同一主题的另一个很好的 Stack Overflow 答案:Best way to do one-to-many "JOIN" in CouchDB
*** 编辑
这里引用了 CouchDB 文档:http://guide.couchdb.org/draft/transforming.html
reduce
函数旨在减少 与给定键关联的值。
CouchDB reduce_limit
用于检测设计不良的 reduce 函数,这是您通过连接值所做的...但是不要惊慌:CouchDB 的任何新手都会犯同样的错误。
在 reduce
函数中连接值的问题在于:
- 完全没有必要(如果你需要整个列表,只需使用一个
map
函数),
- 非常效率低下:您的磁盘上的索引会越来越大,您的磁盘访问时间也会越来越长。
所以...只需编写一个最小的 map
函数,例如:
function(o){
emit(o.meterNumber);
}
不要编写任何 reduce
函数。并使用 include_docs=true
.
调用视图
但也许您对数据格式不满意?
没问题:你有 list
个函数。请记住 map
和 reduce
函数应该用于纯数据处理,而不是用于格式化目的。
我正在使用 CouchDB,我想在查询数据时更好地利用 MapReduce。
我的确切用例如下:
我有很多调查。每个调查都有一个 meterNumber、meterReading 和 meterReadingDate,例如:
{
meterNumber: 1,
meterReading: 2050,
meterReadingDate: 1480000000000
}
然后我使用 Map 函数通过 meterNumber 生成读数。有许多重复的键(在不同日期读取相同的仪表)。即
[
[meterNumber, {reading: xxx, readingDate: xxx}],
[meterNumber, {reading: xxx, readingDate: xxx}],
[meterNumber, {reading: xxx, readingDate: xxx}],
etc
]
然后我在发送到 reduce 函数之前将它们分组,然后 reduce 函数实际上应该扩展值集。 IE。我想要这个:
[
[meterNumber, [{reading:xxx, readingDate: xxx}, {reading:xxx, readingDate: xxx}, {reading:xxx, readingDate: xxx}]],
[meterNumber, [{reading:xxx, readingDate: xxx}, {reading:xxx, readingDate: xxx}, {reading:xxx, readingDate: xxx}]],
[meterNumber, [{reading:xxx, readingDate: xxx}, {reading:xxx, readingDate: xxx}, {reading:xxx, readingDate: xxx}]],
etc
]
为了 运行 CouchDB 上的这个 MapReduce 视图,我必须允许这种类型的结果集 (Couchdb - Is it possible to deactivate the reduce_overflow_error error)。
这表明我可能 运行 遇到大型结果集的性能问题。是这样吗?为什么必须在 CouchDB 上专门启用此设置?
*** 编辑
下面接受的答案向我指出,我在 MapReduce 中所做的事情也可以(并且更好)使用列表。这是关于同一主题的另一个很好的 Stack Overflow 答案:Best way to do one-to-many "JOIN" in CouchDB
*** 编辑
这里引用了 CouchDB 文档:http://guide.couchdb.org/draft/transforming.html
reduce
函数旨在减少 与给定键关联的值。
CouchDB reduce_limit
用于检测设计不良的 reduce 函数,这是您通过连接值所做的...但是不要惊慌:CouchDB 的任何新手都会犯同样的错误。
在 reduce
函数中连接值的问题在于:
- 完全没有必要(如果你需要整个列表,只需使用一个
map
函数), - 非常效率低下:您的磁盘上的索引会越来越大,您的磁盘访问时间也会越来越长。
所以...只需编写一个最小的 map
函数,例如:
function(o){
emit(o.meterNumber);
}
不要编写任何 reduce
函数。并使用 include_docs=true
.
但也许您对数据格式不满意?
没问题:你有 list
个函数。请记住 map
和 reduce
函数应该用于纯数据处理,而不是用于格式化目的。