私は、コレクションの私の文書(包括的な組み込み文書)のすべての鍵を数えたいと思っていました。 まず、私はこれを解決するJavaクライアントを作成しました。結果を表示するまでには4秒以下かかりました。 次にmap/reduce関数を書いた。結果は良かったのですが、この機能を実行するのに30秒以上かかりました! map/reduce関数はサーバ側で実行されているので高速になると思いました。 Javaクライアントはサーバーからすべてのドキュメントを取得する必要がありますが、それははるかに高速です。 なぜそうですか?MongoDB MapReduceは純粋なJava処理よりもはるかに遅いですか?
は、ここに私のmap関数です//:
://ここで
reduce = function (key, emits) {
total = 0;
for (var i in emits) {
total += emits[i].count;
}
return {count:total};
}
のMapReduceの呼び出しです://ここ
map = function(){
for(var key in this) {
emit(key, {count:1});
if(isNestedObject(this[key])){
m_sub(key, this[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クライアントによってカウントされない配列のキーもカウントするためです。 異なる実行時間にいくつかの光を当てていただきありがとうございます。
Mattが言ったように。あなたのマップのスペース要件が、利用可能なメモリの量を上回る操作を減らすとき、私はmongo map-reduceをもっと探しています。それらは、結果を作成するための一時的なコレクションの作成と人口集めを含み(そしてJavaScriptで実行されます)、JVMでの直接的な計算よりも遅いヒープになります。 – Michael
あなたの返事をありがとう!次のジラについては、mongoのマップを使用してパフォーマンスが350倍悪化したと報告されています。 http://jira.mongodb.org/browse/SERVER- 1197 ここでの答えは同じ方向です:http://stackoverflow.com/questions/2599943/2613106#2613106 – Kay
明らかにMongoDB map-reduceはまだシングルスレッドで動作しています。規模が変わらないのも不思議ではありません。非常に平行であることを意図したマップ・リダクションではありません。 –