「收藏」对象不可调用。如果您想调用“mapReduce” “集合”上的方法对象失败,因为不存在这样的方法
我正在使用 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 个唯一键。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
它不叫
mapReduce
,而是map_reduce
。尝试:It's not called
mapReduce
, butmap_reduce
. Try:问题
正如所有答案中提到的,问题在于
pymongo
中的 MapReduce 方法实际上是用下划线编写的,即 map_reduce,以适应最常用的 Python 代码 风格。令人困惑的错误
该错误可能看起来非常令人困惑,并将您引向错误的方向。这里的要点是,MongoDB 使用使用点的内部/系统集合名称,例如
system.namespaces
、system.indexes
、system.profile
等。尽管 MongoDB 不允许您使用点式名称来创建新集合,但无论如何您都可以查询现有的系统集合。因此,当您运行user_actions.mapReduce
代码时,它实际上将user_actions.mapReduce
视为单个集合,即 Collection 对象的实例,然后尝试执行该对象上的 __call__
方法不存在。因此出现错误。好的部分是 pymongo 考虑了这种情况,并提示您尝试在不存在的相应 Collection 对象上执行 mapReduce 方法的可能性。
The Problem
As mentioned in all the answers, the problem is that the MapReduce method in
pymongo
is actually written with underscores, i.e. map_reduce, to fit into the most used Python code style.The Confusing Error
The error might seem very much confusing and take you in the wrong direction. The point here is, that MongoDB uses internal/system collection names that use a dot, e.g.
system.namespaces
,system.indexes
,system.profile
, etc. Although MongoDB does not let you use a dot-ed name to create a new collection, anyway you may query existing system collections. So while you run youruser_actions.mapReduce
code, it actually treatsuser_actions.mapReduce
as a single collection, i.e. instance of Collection object, and then tries to execute the__call__
method on that object, which does not exist. Thus the error.The good part it is that
pymongo
considers this case, and hints about the possibility that you were trying to execute themapReduce
method on the corresponding Collection object which does not exist.再次读取该链接页面,该方法也称为
map_reduce
,在该示例中,
things
是一个集合,当您插入第一个时会创建它里面的文档。read that linked page again, the method is called
map_reduce
also, in that example
things
is a collection, it's get created when you insert the first document in it.对此的一项更新是,PyMongo 4.0 删除了 pymongo.collection.Collection.map_reduce()。使用 4.0+ 版本的 pymongo 会给 map_reduce 方法带来同样的错误。
详细信息可以参见 这里
One update on this, PyMongo 4.0 Removed pymongo.collection.Collection.map_reduce(). Using 4.0+ version of pymongo will give same error for map_reduce method.
Details can be found here