编写MapReduce函数来统计MongoDB中不同用户创建的帖子数量
我在MongoDB中创建了一个包含标题、描述、作者、评论的“帖子”集合,如下所示:编写MapReduce函数来统计MongoDB中不同用户创建的帖子数量,mongodb,mapreduce,nosql,Mongodb,Mapreduce,Nosql,我在MongoDB中创建了一个包含标题、描述、作者、评论的“帖子”集合,如下所示: db.posts.insert({ title:'MongoDB', description:'MongoDB is a NoSQL DB', by:'Tom', comments:[ {user:'ram',
db.posts.insert({
title:'MongoDB',
description:'MongoDB is a NoSQL DB',
by:'Tom',
comments:[
{user:'ram',
message:'We use MongoDB'
}
]
}
)
同样,我添加了另外两个条目。
现在,我想编写MapReduce函数来统计MongoDB中不同用户创建的帖子数量。我用过:
db.posts.mapReduce(
function() { emit(this.user_id,1); },
function(key, values) {return Array.sum(values)}, {
out:"post_total"
}
).find()
此输出:
{"id": null , "value": 3}
但是,我想展示的是:
{ "_id" : "tom_id", "value" : 2 }
{ "_id" : "mark_id", "value" : 1 }
或
将mapReduce方法重新写入:
db.posts.mapReduce(
function() {
emit(this.user_id, 1);
},
function(key, values) {
return Array.sum(values);
},
{ "out": { "inline": 1 } }
)
或者使用runCommand命令运行带有输出集合选项的mapReduce操作:
mr = db.runCommand({
"mapreduce": "posts",
"map" : function() {
for (var key in this) { emit(this.user_id, 1); }
},
"reduce" : function(key, values) { return Array.sum(values); },
"out": "post_total"
})
要获得结果,请对结果集合运行find()
:
db[mr.result].find()
使用聚合框架可获得同等效果,但操作效率更高:
db.posts.aggregate([
{
"$group": {
"_id": "$user_id",
"count": { "$sum": 1 }
}
}
])
最后,我解决了它。我从你那里得到了一些想法
我做错的是,emit(这个.user_id,1)。我传递了错误的键。db.posts.mapReduce(function(){emit(this.user_id,1);},function(key,values){return Array.sum(values);},{“out”:{“inline”:1})。find()输出:[{“id”:null,“value”:3}]不起作用。@SarojShrestha为什么要将find()附加到一个内联输出?没有find()输出“结果”:[{“id”:null,“value”:3}]“timeMillis”:15,“计数”:{“input”:3,“emit”:3,“reduce”:3,“output”:1},“ok”:1}@chirdam感谢您的时间和努力,但它仍然显示id:null。实际上,这是我在董事会考试中提出的一个问题。正如有人明确提到要编写mapreduce函数,所以我特别询问mapreduce。我已经跟随创建了一个集合。这种方法有什么问题吗?但它在“db.posts.find()”中显示良好,但在mapreduce函数中,它会继续生成id:null。@SarojShrestha您是否也使用
aggregate()
方法尝试过其他查询?你的MongoDB版本是什么?仅使用db.posts.find()查询时,输出是什么?
db.posts.aggregate([
{
"$group": {
"_id": "$user_id",
"count": { "$sum": 1 }
}
}
])
db.posts.mapReduce(
function() { emit(this.by,1); },
function(key, values) {return Array.sum(values)}, {
out:"post_total"
}
).find()