我想要计算我的文档(包括嵌入式文档)的所有关键字.首先我写了一个Java客户端来解决这个问题.显示结果只需不到4秒钟.然后我写了一个map / reduce函数.结果很好,但运行该功能花了30多秒!我认为map / reduce函数会更快...
我想要计算我的文档(包括嵌入式文档)的所有关键字.
首先我写了一个Java客户端来解决这个问题.显示结果只需不到4秒钟.
然后我写了一个map / reduce函数.结果很好,但运行该功能花了30多秒!
我认为map / reduce函数会更快,因为它是在服务器端执行的. Java客户端需要从服务器获取每个文档,但速度要快得多.
为什么会这样?
//这是我的地图功能:
map = function(){
for(var key in this) {
emit(key, {count:1});
if(isNestedObject(this[key])){
m_sub(key, this[key]);
}
}
}
//这是我的reduce函数:
reduce = function (key, emits) {
total = 0;
for (var i in emits) {
total += emits[i].count;
}
return {count:total};
}
//这是对mapreduce的调用:
mr = db.runCommand({"mapreduce":"keyword", "map" : map, "reduce" : reduce,
"scope":{
isNestedObject : function (v) {
return v && typeof v === "object";
},
m_sub : function(base, value) {
for(var key in value) {
emit(base + "." + key, {count:1});
if(isNestedObject(value[key])){
m_sub(base + "." + key, value[key]);
}
}
}
}
})
//这是输出:
{
"result" : "tmp.mr.mapreduce_1292252775_8",
"timeMillis" : 39087,
"counts" : {
"input" : 20168,
"emit" : 986908,
"output" : 1934
},
"ok" : 1
}
//这是我的Java客户端:
public static Set<String> recursiv(DBObject o){
Set<String> keysIn = o.keySet();
Set<String> keysOut = new HashSet<String>();
for(String s : keysIn){
Set<String> keys2 = new HashSet<String>();
if(o.get(s).getClass().getSimpleName().contains("Object")){
DBObject o2 = (DBObject) o.get(s);
keys2 = recursiv(o2);
for(String s2 : keys2){
keysOut.add(s + "." + s2);
}
}else{
keysOut.add(s);
}
}
return keysOut;
}
public static void main(String[] args) throws Exception {
final Mongo mongo = new Mongo("xxx.xxx.xxx.xxx");
final DB db = mongo.getDB("keywords");
final DBCollection keywordTable = db.getCollection("keyword");
Multiset<String> count = HashMultiset.create();
long start = System.currentTimeMillis();
DBCursor curs = keywordTable.find();
while(curs.hasNext()){
DBObject o = curs.next();
Set<String> keys = recursiv(o);
for(String s : keys){
count.add(s);
}
}
long end = System.currentTimeMillis();
long duration = end - start;
System.out.println(new SimpleDateFormat("mm:ss:SS").format(Long.valueOf(duration)));
System.out.println("duration:" + duration + " ms");
//System.out.println(count);
System.out.println(count.elementSet().size());
}
//这是输出:
00:03:726
duration:3726 ms
1898
不要担心不同的结果数量(1934年与1898年).这是因为map reduce也计算了数组中的键,这些键不是由java客户端计算的.
感谢您了解不同的执行时间.
解决方法:
这不是一个很好的答案,但在o’reilly mongo书中,kristina说map-reduce查询是你能做的最慢的事情之一,但它们也是最灵活,最具扩展性的. Mongo将能够拆分查询并处理所有节点的处理能力,这意味着您应该为添加的每个节点获得线性可伸缩性.但是在单个节点上,即使按查询分组也会比map reduce更快.
本文标题为:MongoDB MapReduce比纯Java处理慢得多?
基础教程推荐
- Java数据结构之堆(优先队列)详解 2023-03-22
- java – 使用oracle.jdbc.driver.OracleConnection的类强制转换异常 2023-11-03
- SpringBoot分页的实现与long型id精度丢失问题的解决方案介绍 2023-06-10
- java常见log日志的使用方法解析 2023-02-27
- Springboot整合zookeeper实现对节点的创建、监听与判断的案例详解 2023-01-29
- Maven实现项目构建工具 2023-03-06
- img的src地址是一个请求的方式来显示图片方法 2023-08-01
- Spring Cloud OpenFeign 远程调用 2022-09-03
- Java设计模式之模板方法模式Template Method Pattern详解 2023-07-01
- Java模拟QQ实现聊天互动程序 2022-12-16