map reduce with stored javascript functions

896 views
Skip to first unread message

Laura Dietz

unread,
Aug 24, 2011, 6:09:18 PM8/24/11
to mongod...@googlegroups.com
Dear List,

I have a combination of map-reduce commands that have to be performed in
that order.
Each map/reduce/finalize method is stored in db.system.js

I have another javascript function "doIt" ties all commands together
sets scope arguments etc.

I could save doIt in the db.system.js as well and call
db.eval("doIt()"), but for blocking reasons I don't want to do this.

However, if I just call doIt on the client, it can't resolve the
functions stored in db.system.js.

doIt = function() {
innerfunction = function(arg1, arg2) {
db[arg2+"a"].mapReduce(map1, reduce1, {out:
{reduce:tmpCollection}, scope:{"arg1":arg1}})
db[arg2+"b"].mapReduce(map1, reduce1, {out:
{reduce:tmpCollection}, scope:{"arg1":arg2}})

db.tmpCollection.mapReduce(map2, reduce2, {out:
{reduce:arg2+"outCollection"}})
}
innerfunction(4, "collectionOne");
innerfunction(1, "collectionTwo");
// more complicated logic here...
}

I would like to call doIt() on the mongo shell.

When I call doIt() on the mongo shell I get
> ReferenceError: map is not defined (shell)


Note that just calling the following command on the shell works without
the wrapping.
db.collection.mapReduce(map, reduce, {out: {reduce:"outCollection"}})


Is there a command to say "resolve this using the saved function"?
Alternatively, can I fetch the function from db.system.js?

Thanks,
Laura


Sam Millman

unread,
Aug 24, 2011, 6:33:59 PM8/24/11
to mongod...@googlegroups.com
I am not sure if you understand what system.js is for but stored JS functions are designed to be used within processing so I am not even completly sure how:


db.collection.mapReduce(map, reduce, {out: {reduce:"outCollection"}})

Resolves stored functions as you say since the mongo shell does not understand where to take map and reduce from.



--
You received this message because you are subscribed to the Google Groups "mongodb-user" group.
To post to this group, send email to mongod...@googlegroups.com.
To unsubscribe from this group, send email to mongodb-user...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/mongodb-user?hl=en.


Antoine Girbal

unread,
Aug 26, 2011, 5:53:58 PM8/26/11
to mongodb-user
to access any stored function, you need to be executing the code
server side, using eval for example.
Whenever some JS code is executed on client side, any of your stored
code will error as not found.
Executing a mapreduce within an eval is a bad idea, since eval() takes
a write lock for the entire time.
Bottom line:
- dont use eval
- you may not need stored function
- if you need some, they can only be accessed from within code that
executes on server, like within map() or reduce()
AG

Stanislav Pogrebnyak

unread,
Sep 23, 2011, 2:52:27 AM9/23/11
to mongod...@googlegroups.com
I'v got the same requrements, to call external functions inside map/reduce functions. 
How normally people do that?

Maybe thereis an article about visibility and access for map reduce jobs, and how that area can be altered?

Thanks a lot!

Sam Millman

unread,
Sep 23, 2011, 3:07:28 AM9/23/11
to mongod...@googlegroups.com
Inside MR functions is simple.

You can actually just call it:

storedFunction();

you can use eval but in this case you don't need to.

--
You received this message because you are subscribed to the Google Groups "mongodb-user" group.
To view this discussion on the web visit https://groups.google.com/d/msg/mongodb-user/-/QsRyXdYqVU0J.

Antoine Girbal

unread,
Sep 23, 2011, 3:43:26 AM9/23/11
to mongodb-user
store a function server side:
db.system.js.save({_id: "myfunc", value: function(){print("hello");}})

Then call myfunc() in your map/reduce/finalize.

Stanislav Pogrebnyak

unread,
Sep 23, 2011, 3:47:58 AM9/23/11
to mongod...@googlegroups.com

Thanks for a fast responce, 

Ok, seems like obvious behaviour. 

Reply all
Reply to author
Forward
0 new messages