Error: "emit is not defined" when handling subdue

328 views
Skip to first unread message

Maggie

unread,
Mar 28, 2016, 11:36:18 PM3/28/16
to mongodb-user
Hi, I am working on joining two collection to build a new collection for my project. I read http://tebros.com/2011/07/using-mongodb-mapreduce-to-join-2-collections/

I have 






business

{

                 ....

                 "business_id": "5UmKMjUEUNdYWqANhGckJw",

                  "state": "PA"


review

{

                  ....

                  “votes”:{

                  “funny”:1,

                  “useful”: 1,

                  “cool”: 1

}

“business_id”: “HzLADFJIAOWFJAO”

}

 

I really want to join business and review together in order to get the top20 business_id with highest "cool" value in given state. I have "emit not defined" when I do

res=db.review.mapReduce(review_map, r, {out:{reduce:"top20"}});

review_map=function(){
   emit(this.business_id, {cool: this.votes.cool})
}

I modified the review_map as followed. I run res=db.review.mapReduce(review_map, r, {out:{reduce:"top20"}}); again and I get "this.votes is undefined" this time.
review_map=function(){
     var vote=this.votes.cool;
     emit(this.business_id, {cool: vote})
}





Asya Kamsky

unread,
Mar 31, 2016, 7:52:00 PM3/31/16
to mongodb-user
I recommend using aggregation rather than map-reduce - using $lookup will give you ability to look up what you want to look up, but the linked blog post Map Reduce code is incorrect (it's been discussed on the list before, probably I should just add a comment on the page so people will stop wasting their time trying to understand why things aren't working).

Unfortunately, "top 20" is difficult to do in the current version of aggregation - 3.4 will add some expressions that will make it simpler.   For now you can do something similar to this (and this assumes that the number of businesses with more than 1 "cool" vote for each state is smaller than 16MBs.   If this is the Yelp sample data set, you're fine as the entire data set is 133 MBs.

Try this:

db.review.aggregate( [
{$match:{"votes.cool":{$gt:0}}},
{$lookup:{from:"business",localField:"business_id",foreignField:"_id",as:"biz"}},
{$unwind:"$biz"},
{$group:{_id:{state:"$biz.state",biz:"$business_id",bizname:"$business_name"},sum:{$sum:"$votes.cool"}}},
{$sort:{"_id.state":1, "sum":-1}},
{$group:{_id:"$_id.state", allBiz:{$push:{biz:"$_id.bizname",coolVotes:"$sum"}}}},
{$project:{_id:0, state:"$_id", top20coolBiz:{$slice:["$allBiz",20]}}}
] )

Note that in my schema the business collection has business_id in the field called "_id".   If yours is only in "business_id" you should change foreignField to be "business_id" and you must absolutely make sure you have an index on business.business_id otherwise this query will take forever.

Asya


--
You received this message because you are subscribed to the Google Groups "mongodb-user"
group.
 
For other MongoDB technical support options, see: https://docs.mongodb.org/manual/support/
---
You received this message because you are subscribed to the Google Groups "mongodb-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mongodb-user...@googlegroups.com.
To post to this group, send email to mongod...@googlegroups.com.
Visit this group at https://groups.google.com/group/mongodb-user.
To view this discussion on the web visit https://groups.google.com/d/msgid/mongodb-user/e228c2d3-3f69-4b45-ae10-5cdf5ead6c82%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Asya Kamsky
Lead Product Manager
MongoDB
Download MongoDB - mongodb.org/downloads
Free MongoDB Monitoring - cloud.mongodb.com
Free Online Education - university.mongodb.com
Get Involved - mongodb.org/community
We're Hiring! - https://www.mongodb.com/careers
Reply all
Reply to author
Forward
0 new messages