On Apr 29, 2009, at 7:31 AM, Paul Davis wrote:
Jurg van Vliet wrote:
hi people,
(this is my first 'sound' on this list, so hi again. i am enjoying
couchdb, especially when seeing how many people are having fun
doing 'something different'. so, thank you for showing me what you
are doing.)
for our project we am using couchdb as the general datastore. we
store everything in a document in couchdb, and we distiguish type
explicitly (with a field in the document.) suppose we have articles
and files and comments.
both articles and files have (nested) comments. a comment stores
its path, and this way models its ancestry. there is no reference
from either article or file to comments, as this is not necessary.
(getting this to work with couchdb already forced us to learn (and
accept) couchdb for what it is :) difficult, but fun!)
now, suppose we want to list articles ordered by the number of
comments. at first glance this is easy, and the solution is similar
to the tag solutions you find by googling. but we want a view that
gives us only the articles, we don't want the files. (we want
separate views for files, and other types of documents containing
comments.)
the solution we thought of was 'a bit of a hack', but it should
work. the map code for the document type article looks like this
function(doc) {
if( doc.type == 'Article') {
emit( doc._id, 0);
} else if( doc.type == 'Comment') {
emit( doc.path[0], 1);
} else {
emit( doc._id, "a");
}
}
Is there a reason you have this last emit statement? There's nothing
forcing you to emit anything. So you could just delete the last if
clause and then those docs won't be in your reduce. In the only way
to drop a reduce row is to not emit it.
if i don't emit anything in the last emit statement i get comments for
all of my document types. then case i end up with a list of articles
and comments, both with a comment count.
Paul Davis
here you see that we emit everything, but we emit a non-number
value when the type is not what we want. a simple reduce would drop
the rows that have values that are not-a-number leaving us with
exactly what we want. the reduce could look like this:
function( keys,values,rereduce) {
var total = sum( values);
if( !isNaN( total)) {
return total;
}
}
but this gives an error about a 'bad_cause', at least in futon.
adding something like 'return null' doesn't help very much, because
it doesn't exclude what we don't want to see.
my questions are
1. how can we exclude things from the result of the view with
reduce, in other words 'how to drop rows with reduce'?
2. how else can you attack this problem?
thanks,
jurg.
a little of bit of context: we are creating a rails application
following basic_model and couchrest. everyone is still struggling
with understanding couchdb, including us. so we decided to stick
with this for a while, and patch little things for what we need in
our application. we choose to design the documents as close as
possible to the rails models. as a result we implemented views on
the level of a model, because that is the way we look at our
problem. we have certain views for articles, for files, for users,
etc. perhaps this direction of implementation doesn't get us to
where we want to go. so (almost) any suggestion is welcome:) we
still want to have multiple types of information in one couchdb
database, though.