views:

85

answers:

2

related to http://stackoverflow.com/questions/2127374/mongodb-group-using-ruby-driver

if I want to do something like the following in SQL:

select page_id, count(page_id) from a_table group by page_id

I thought the MongoDB's doc says

http://api.mongodb.org/ruby/current/Mongo/Collection.html#group-instance_method

group(key, condition, initial, reduce, finalize = nil)
# returns an array

So from the other post, I am using:

Analytic.collection.group(  "fucntion (x) return {page_id : x.page_id}", 
                            nil, 
                            {:count => 0},  
                            "function(x, y) { y.count++ }"  )

but it actually returns

[{"count"=>47.0}] 

which is the total number of records (documents) in the collection. Is something not correct above? I thought the key might be a static string like in

http://kylebanker.com/blog/2009/11/mongodb-count-group/

db.pageviews.group(
{
 key: {'user.agent': true}, 
 initial: {sum: 0}, 
 reduce: function(doc, prev) { prev.sum += 1}
});

but it is not in the other stackoverflow post.

Update: actually, in the link above, the solution like

Analytic.collection.group(  ['page_id'], nil, 
  {:count => 0},  "function(x, y) { y.count++ }"  )

works, but just wonder why the first method in this post didn't work.

+1  A: 

The reason the first example didn't work is that you misspelled "function" as "fucntion". The following should work:

Analytic.collection.group( "function(x){ return {page_id : x.page_id}; }", 
                           nil, 
                           { :count => 0 },  
                           "function(x, y){ y.count++; }" )
Pan Thomakos
if I correct the spelling, that line will return `[{"page_id"=>nil, "count"=>47.0}]` still...
動靜能量
You should make sure that your data actually has values for page_id besides nil. That result seems to indicate that all 47 documents have a page_id of nil. I am using version 1.6.0 of mongodb and gem 1.0.7 and cannot say for certain whether or not previous versions of either of these might produce different results.
Pan Thomakos
A: 

I finally got it to work by

Analytic.collection.group(  ['myapp_id'], {:page => 'products'}, 
  {:pageviews => 0, :timeOnPage => 0},  
  "function(x, y) { y.pageviews += x.pageviews;  y.timeOnPage += x.timeOnPage }"  )

but then I used Map/Reduce afterwards as Map/Reduce seems like a more generic and powerful method.

動靜能量