Can someone provide an example with the the correct syntax to pass a function to the scope parameter when using pymongo's map_reduce.
So far I have only found examples of passing a function in javascript (How to use variables in MongoDB Map-reduce map function), and passing variables with pymongo (Map reduce execute failed with pymongo but success in mongo shell).
Upon trying I am always getting "TypeError: foo is not a function", and from the server logs it looks like it has taken the function I passed to the scope as a string.
1 Answer 1
I fiddled with this quite a bit today. The scope
keyword argument needs to be a dictionary. If you want to define a variable that will be a function in the scope of the mapper, put its name as the key, and provide the function declaration wrapped in a Code()
constructor. Here's what should be a working example with MongoDB v3.2.8 and pymongo v3.3.1:
import pymongo
import bson
db = pymongo.MongoClient().test
db['test-input'].insert_many([
{'foo': 'bar', 'angle': 0},
{'foo': 'bar', 'angle': 90},
{'foo': 'baz', 'angle': -90}
])
mapper = bson.Code(
"""
function map() {
emit(this.foo, radians(this.angle))
}
"""
)
reducer = bson.Code(
"""
function reduce(key, values) {
var avg = 0;
for (i in values) {
avg += values[i];
}
return avg / values.length;
}
"""
)
output_collection = db['test-input'].map_reduce(
mapper, reducer, 'test-output',
scope={
'radians': bson.Code("function(x) {return x * Math.PI / 180}")
}
)
print [x for x in output_collection.find()]