ajreal
ajreal

Reputation: 47321

Reduce output must shrink more rapidly, what is this error about?

An user can post multiple comments in a thread, and I try to get list of threads (distinct) that an user has make comment to it, like :-

// 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;

This is pretty easy in MySQL.
But to convert to couchdb :-

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

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

If I using the above map function, I will hit into an error like :-

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

I think I have applied the reduce function in wrong manner.

If using another way, like :-

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

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

The group=true result is look exactly what mysql group-by does.
However, I'm unable to get ALL the list of thread by an user (given I only have the user_id during query time)

Third way, I can discard use of map reduce, and directly apply :-

emit(doc.user_id, doc.thread_id);

And do an PHP array like

foreach ( ... )
{
  $threads[$thread_id] = TRUE;
}
array_keys($threads);

However, this is quite bloated and less efficient.

Second method look more accurate :-

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

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

Is there a way to get all result without knowing the thread_id ?

(ps: I new to couchdb, and I might have describe the scenario in a bad manner)

Some reference I gotten via @jasonsmith :- http://guide.couchdb.org/draft/cookbook.html

As a rule of thumb, the reduce function should reduce to a single scalar value. That is, an integer; a string; or a small, fixed-size list or object that includes an aggregated value (or values) from the values argument. It should never just return values or similar. CouchDB will give you a warning if you try to use reduce “the wrong way”:

Upvotes: 4

Views: 3462

Answers (1)

ajreal
ajreal

Reputation: 47321

Follow closely to what this docs saying :- 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;
}

Query :-

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

And the result now is accurate,
so the problem is lied on the reduce function and how the query being construct.

Upvotes: 1

Related Questions