减少输出必须更快收缩,这个错误是什么?

时间:2011-11-30 10:12:40

标签: couchdb

用户可以在一个帖子中发布多个评论,并尝试获取用户对其进行评论的线程列表(不同),例如: -

// comment table (relation table)
id, thread_id, user_id

select comment.thread_id, count(*)
from user
inner join comment on user.id=comment.user_id
where user.id = ?
group by comment.thread_id;

这在MySQL中非常简单 但要转换为couchdb: -

// map
function(doc)
{
  emit(doc.user_id, doc.thread_id);
}

// reduce
function (key, thread_id)
{
  return thread_id;
}

如果我使用上面的地图功能,我会遇到如下错误: -

"error": "reduce_overflow_error",
"reason": "Reduce output must shrink more rapidly: Current output: ...

我想我已经以错误的方式应用了reduce功能。

如果使用其他方式,例如: -

// map
function (doc)
{
   emit([doc.user_id, doc.thread_id], 1);
}

// reduce
function(keys, values)
{
  return sum(values);
}

group=true结果看起来与mysql group-by完全相同 但是,我无法通过用户获取所有线程列表(假设我在查询时间内只有user_id)

第三种方式,我可以放弃使用map reduce,并直接应用: -

emit(doc.user_id, doc.thread_id);

做一个像

这样的PHP数组
foreach ( ... )
{
  $threads[$thread_id] = TRUE;
}
array_keys($threads);

然而,这是非常臃肿和效率低下的。

第二种方法看起来更准确: -

key=[user_id, *] <-- it does not work, believe only work on exact match

key=[user_id, thread_id] <-- return one row

有没有办法在不知道thread_id的情况下获得所有结果?

(ps:我是couchdb的新手,我可能会以糟糕的方式描述这个场景)

我通过@jasonsmith得到的一些参考: - http://guide.couchdb.org/draft/cookbook.html

  

根据经验,reduce函数应减少到单个标量值。也就是说,一个整数;一串;或者包含来自values参数的聚合值(或多个值)的小型固定大小的列表或对象。它永远不应该只返回值或类似。如果您尝试使用reduce“错误的方式”,CouchDB会给您一个警告:

1 个答案:

答案 0 :(得分:1)

密切关注本文所说的内容: - http://wiki.apache.org/couchdb/View_Snippets#Generating_a_list_of_unique_values

// map
function(doc)
{
  emit([doc.user_id, doc.thread_id], null);
}

// reduce
function (keys, values)
{
  return null;
}

查询: -

?startkey=["$uid"]&endkey=["$uid",{}]&group=true

结果现在是准确的,
所以问题就在于reduce函数以及构造查询的方式。