gpt4 book ai didi

java - MongoDB MapReduce 比纯 Java 处理慢很多?

转载 作者:可可西里 更新时间:2023-11-01 09:18:19 26 4
gpt4 key购买 nike

我想计算一个集合中我的文档(包括嵌入式文档)的所有键。首先我写了一个Java客户端来解决这个问题。显示结果用了不到 4 秒。然后我写了一个 map/reduce 函数。结果很好,但运行函数花了 30 多秒!我认为 map/reduce 函数会更快,因为它是在服务器端执行的。 Java 客户端需要从服务器获取每个文档,但速度要快得多。为什么会这样?

//这是我的 map 函数:

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 将能够分解查询并处理所有节点的处理能力,这意味着您应该通过添加的每个节点获得线性可扩展性。但是在单个节点上,即使是 group by query 也会比 map reduce 更快。

关于java - MongoDB MapReduce 比纯 Java 处理慢很多?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4430407/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com