4

我正在使用 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 个唯一键

4

4 回答 4

6

它不叫mapReduce,而是map_reduce。尝试:

results = db.user_actions.map_reduce(map, reduce, "user_entities_interactions")
于 2011-08-05T21:51:06.457 回答
2

问题

正如所有答案中提到的,问题在于 MapReduce 方法pymongo实际上是用下划线编写的,即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 使用使用的内部/系统集合名称,例如system.namespaces, system.indexes,system.profile等。尽管 MongoDB 不允许您使用名称来创建新集合,但无论如何您都可以查询现有的系统集合。因此,当您运行user_actions.mapReduce代码时,它实际上将其user_actions.mapReduce视为单个集合,即 Collection 对象的实例,然后尝试在该对象上执行该__call__方法,该对象不存在。因此错误。

好的部分是pymongo考虑到这种情况,并提示您尝试在mapReduce不存在的相应 Collection 对象上执行该方法的可能性。

于 2015-05-05T22:01:43.833 回答
0

再次阅读该链接页面,该方法被调用map_reduce

此外,在该示例things 中是一个集合,它是在您将第一个文档插入其中时创建的。

于 2011-08-05T21:50:01.903 回答
0

对此的一个更新,PyMongo 4.0 删除了 pymongo.collection.Collection.map_reduce()。使用 4.0+ 版本的 pymongo 会给 map_reduce 方法同样的错误。

详细信息可以在这里找到

于 2022-02-06T07:10:49.557 回答