我需要使用mapReduce和/或聚合进行此分析:
DBCollection coll = db.getCollection("documents");
DBCursor cursor = coll.find();
Map<String,Integer> map = new HashMap<String,Integer>();
while(cursor.hasNext()){
DBObject obj = cursor.next();
BasicDBList list = (BasicDBList)obj.get("cats");
for(int i=0;i<list.size();i++){
String cat = list.get(i).toString();
int hits = 0;
if(map.containsKey(cat)){
hits = map.get(cat);
}
hits++;
map.put(cat, hits);
}
}
有人可以给我一个关于如何使用mapReduce和聚合实现我所需要的东西的正确示例吗?
谢谢!
最佳答案
您似乎正在计算数组中元素的唯一出现次数。无论内容是什么,都没有关系,因为您只是在映射中转换为字符串键。但这是一个示例:
{ "cats" : [ 1, 2, 3, 4, 5 ] }
{ "cats" : [ 2, 4 ] }
{ "cats" : [ 1, 5 ] }
{ "cats" : [ 4, 5 ] }
聚合框架是最快的:
db.cats.aggregate([
{ "$unwind": "$cats" },
{ "$group": {
"_id": "$cats",
"count": { "$sum": 1 }
}}
])
产生:
{ "_id" : 5, "count" : 3 }
{ "_id" : 4, "count" : 3 }
{ "_id" : 3, "count" : 1 }
{ "_id" : 2, "count" : 2 }
{ "_id" : 1, "count" : 2 }
Map reduce大致相同,但速度较慢:
db.cats.mapreduce(
function() {
this.cats.forEach(function(cat) {
emit( cat, 1 );
});
},
function(key,values) {
return Array.sum( values );
},
{ "out": { "inline": 1 } }
)