我正在使用pyMongo 1.11和MongoDB 1.8.2。我正在尝试做一个相当复杂的Map / Reduce。我在Mongo中对函数进行了原型设计并使其正常工作,但是当我尝试将其转换为Python时,我得到了:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/Developer/R-and-D/<ipython-input-71-3c3a43221538> in <module>()
----> 1 results = db.user_actions.mapReduce(map, reduce, "user_entities_interactions")
/Library/Python/2.7/site-packages/pymongo/collection.pyc in __call__(self, *args, **kwargs)
1099 "call the '%s' method on a 'Collection' object it is "
1100 "failing because no such method exists." %
-> 1101 self.__name.split(".")[-1])
TypeError: 'Collection' object is not callable. If you meant to call the 'mapReduce' method on a 'Collection' object it is failing because no such method exists.
我的收藏如下:
{ "_id" : ObjectId("..."), "entity_id" : 1556, "user_id" : 466112 }
{ "_id" : ObjectId("..."), "entity_id" : 1366, "user_id" : 10057 }
{ "_id" : ObjectId("..."), "entity_id" : 234, "user_id" : 43650 }
{ "_id" : ObjectId("..."), "entity_id" : 6, "user_id" : 34430 }
{ "_id" : ObjectId("..."), "entity_id" : 461, "user_id" : 3416 }
{ "_id" : ObjectId("..."), "entity_id" : 994, "user_id" : 10057 }
{ "_id" : ObjectId("..."), "entity_id" : 296, "user_id" : 466112 }
我在Python中运行的代码是:
map = Code("""function () {
emit(this.user_id, {
user_id : this.user_id,
entity_id : this.entity_id});
}""")
reduce = Code("""function (key, values) {
var entities = { user_id : values[0].user_id, entity_id : [ ] };
for (var i = 0; i < values.length; i++) {
entities.entity_id[i] = values[i].entity_id;
}
return entities;
}""")
results = db.user_actions.mapReduce(map, reduce, "user_entities_interactions")
应该的结果是:
{ "_id" : 3416, "value" : { "user_id" : 3416, "entity_id" : 461 } }
{ "_id" : 10057, "value" : { "user_id" : 10057, "entity_id" : [ 1366, 994 ] } }
{ "_id" : 34430, "value" : { "user_id" : 34430, "entity_id" : 6 } }
{ "_id" : 43650, "value" : { "user_id" : 43650, "entity_id" : 234 } }
{ "_id" : 466112, "value" : { "user_id" : 466112, "entity_id" : [ 1556, 296 ] } }
我不清楚问题是什么。该错误表明'Collection'对象没有mapReduce方法,但显然不是这样,因为http://api.mongodb.org/python/current/examples/map_reduce.html的示例有效,如果不是集合,那么'事物'是什么?
另外,如果你想知道我为什么不用group()这样做,那是因为我有超过20000个唯一键。
答案 0 :(得分:5)
它不是mapReduce
,而是map_reduce
。尝试:
results = db.user_actions.map_reduce(map, reduce, "user_entities_interactions")
答案 1 :(得分:2)
问题
正如所有答案中所提到的,问题是pymongo
中的MapReduce方法实际上是用下划线写的,即map_reduce,以适应最常用的Python代码样式。
令人困惑的错误
TypeError: 'Collection' object is not callable. If you meant to call the 'mapReduce' method on a 'Collection' object it is failing because no such method exists.
错误可能看起来非常令人困惑,并且会带您走错方向。这里的要点是,MongoDB使用使用 dot 的内部/系统集合名称,例如system.namespaces
,system.indexes
,system.profile
等。虽然MongoDB不允许您使用 dot -ed名称来创建新集合,但无论如何您可以查询现有系统集合。因此,当您运行user_actions.mapReduce
代码时,它实际上将user_actions.mapReduce
视为单个集合,即Collection对象的实例,然后尝试对该对象执行__call__
方法,而不是存在。因此错误。
pymongo
考虑这种情况的好处是,并且暗示了您尝试在不存在的相应Collection对象上执行mapReduce
方法的可能性。
答案 2 :(得分:0)
再次阅读该链接页面,该方法称为map_reduce
另外,在该示例中,things
是一个集合,当您在其中插入第一个文档时,它就会被创建。