我发现了一堆 map_reduce 教程,但它们似乎都没有“where”子句或任何其他方式来从正在考虑的内容中排除文档/记录。我正在处理一个看似简单的查询。我有一个包含时间戳、IP 地址和事件 ID 的基本事件日志文件。我想在给定的时间戳范围内为给定的事件获取唯一用户数。听起来很简单!
我构建了一个类似这样的查询对象:
{'ts': {'$gt': 1345840456, '$lt': 2345762454}, 'cid': '2636518'}
有了这个,我尝试了两种方法,一种使用 distinct,另一种使用 map_reduce:
不同
db.alpha2.find(查询).distinct('ip').count()
在 mongo shell 中,您可以将查询作为 distinct 函数的第二个参数,它在那里工作,但我了解到您不能在 pymongo 中这样做。
Map_reduce
map = Code("function () {"
" emit(this.ip, 1);"
"}")
reduce = Code("function (key, values) {"
" var total = 0;"
" for (var i = 0; i < values.length; i++) {"
" total += values[i];"
" }"
" return total;"
"}")
totaluniqueimp = db.alpha2.map_reduce(map, reduce, "myresults").count();
(我意识到 reduce 函数正在做我不需要的事情,我从演示中拿走了它)。这工作正常,但没有使用我的“where”参数。我试试这个:
totaluniqueimp = db.alpha2.find(query).map_reduce(map, reduce, "myresults").count();`
我得到这个错误:
AttributeError: 'Cursor' object has no attribute 'map_reduce'
结论
基本上,这就是我在 mysql 中尝试做的事情:
select count(*) from records where ts<1000 and ts>900 and campaignid=234 group by ipaddress
看起来很简单!你如何在 mongo 中做到这一点?
更新:回答
根据下面德米特里的回答,我能够解决(并简化)我的解决方案(这是否尽可能简单?):
#query is an object that was built above this
map = Code("function () { emit(this.ip, 1);}")
reduce = Code("function (key, values) {return 1;}")
totaluniqueimp = collection.map_reduce(map, reduce, "myresults", query=query).count();
谢谢德米特里!
最佳答案
你可以尝试使用这个:
totaluniqueimp = db.alpha2.map_reduce(map, reduce, {
out: "myresults",
query: {'ts': {'$gt': 1345840456, '$lt': 2345762454}, 'cid': '2636518'}
}).count();
更新:上面的语句在 mongo shell 中有效。在 pymongo 中,您应该将查询添加为第四个参数:
totaluniqueimp = db.alpha2.map_reduce(map, reduce, "myresults", query={'ts': {'$gt': 1345840456, '$lt': 2345762454}, 'cid': '2636518'})
详细的文档可以在here中找到。
关于python - map_reduce() *和* find() 在同一查询中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12223518/