2011-01-27 19 views
7

मैं, MongoDB जावा ड्राइवर का उपयोग कर एक संग्रह से एक औसत मूल्य की गणना करने कोशिश कर रहा हूँ इस तरह:MongoDB और NumberLong साथ औसत गणना करने के लिए कैसे

DBObject condition = 
    new BasicDBObject("pluginIdentifier", plugin.getIdentifier()); 

DBObject initial = new BasicDBObject(); 

initial.put("count", 0); 
initial.put("totalDuration", 0); 
String reduce = "function(duration, out) { out.count++; 
    out.totalDuration+=duration.floatApprox; }"; 
String finalize = "function(out) { out.avg = out.totalDuration.floatApprox/
    out.count; }"; 

DBObject avg = durationEntries.group(
    new BasicDBObject("pluginIdentifier", true), 
    condition, initial, reduce, finalize); 

System.out.println(avg); 

"अवधि" एक NumberLong (जावा में है यह, एक लंबा है, शायद जावा चालक इसे बदल देता है)। मैं कुछ खोज के बाद पता लगा आदेश, संख्या को निकालने के लिए .floatApprox का उपयोग करने में एक तरह से जाने के लिए था, और यह भी MongoDB कंसोल में काम करता है कि:

> db.DurationEntries.findOne().duration.floatApprox 
5 

हालांकि, इसके बाद के संस्करण जावा कोड चल नहीं होगा एक औसत की गणना, लेकिन रिटर्न इस बजाय

[{"pluginIdentifier":"dummy", "count":7.0, "totalDuration":NaN, "avg":NaN}] 

मैं कई रूप की कोशिश की, साथ और .floatApprox बिना, लेकिन केवल अब तक कुछ अजीब स्ट्रिंग concatenations प्राप्त करने के लिए सक्षम है।

मेरा प्रश्न है: मैं गलत क्या कर रहा/मुझे नंबर संख्या कॉलम के औसत की गणना करने के लिए कैसे जाना चाहिए?

+1

क्या कुंजी यहां है कि आप कॉलम डेटा को जावा में खींचने के बजाय औसत को मोंगो करना चाहते हैं? क्या आप वाकई अपने अवधि के दौरान गलती से कोई गैर-संख्यात्मक डेटा नहीं रखते हैं? –

+0

हां, यह मेरा इरादा है, स्मृति में बजाए डेटाबेस में गणना करने के लिए (क्योंकि जब मेरे पास बहुत सारी प्रविष्टियां होंगी, तो मुझे लगता है कि मेरा जेवीएम स्मृति से बाहर हो जाएगा)। और हां वास्तव में गैर-संख्यात्मक डेटा हो सकता है क्योंकि "शून्य" औसत प्रविष्टियां हो सकती हैं - मैं –

+2

की जांच करूंगा यदि आप चाहते हैं कि औसत एक औसत है, तो मुझे बड़ी मात्रा में स्मृति नहीं लेनी चाहिए, क्योंकि मुझे लगता है, क्योंकि आप प्रत्येक प्रविष्टि को स्मृति में रखने की आवश्यकता नहीं है, केवल कुल योग और गिनती है। मैं मोंगो के साथ बिल्कुल परिचित नहीं हूं कि कैसे, लेकिन यदि आप क्वेरी से परिणाम सेट बैच कर सकते हैं तो आप एक समय में एक सबसेट को संसाधित कर सकते हैं। –

उत्तर

6

यदि आपको मानचित्र/समस्या के साथ समस्याएं आ रही हैं तो आपको शायद मोंगोड कंसोल में गिरा देना चाहिए, इसे वहां से बाहर करें और फिर इसे अपने ड्राइवर में अनुवाद करें।

उदाहरण के लिए, निम्नलिखित दस्तावेजों: इस प्रकार

db.tasks.find() 
{ "_id" : ObjectId("4dd51c0a3f42cc01ab0e6506"), "duration" : 10, "name" : "StartProcess", "date" : "20110501" } 
{ "_id" : ObjectId("4dd51c0e3f42cc01ab0e6507"), "duration" : 11, "name" : "StartProcess", "date" : "20110502" } 
{ "_id" : ObjectId("4dd51c113f42cc01ab0e6508"), "duration" : 12, "name" : "StartProcess", "date" : "20110503" } 

आप MapReduce लिखते थे StartProcess की औसत अवधि की गणना करने के:

m = function(){ 
    emit(this.name , { totalDuration : this.duration , num : 1 }); 
}; 

r = function (name, values){ 
    var n = {totalDuration : 0, num : 0}; 
    for (var i=0; i<values.length; i++){ 
    n.totalDuration += values[i].totalDuration; 
    n.num += values[i].num; 
    } 
    return n; 
}; 

f = function(who, res){ 
    res.avg = res.totalDuration/res.num; 
    return res; 
}; 

उसके बाद, आप MongoDB उपयोग कर रहे हैं यह सोचते हैं 1.7 या ऊपर:

db.tasks.mapReduce(m, r, { finalize : f, out : {inline : 1} }); 

आपको निम्न उत्तर देगा:

"results" : [ 
    { 
    "_id" : "StartProcess", 
     "value" : { 
     "totalDuration" : 33, 
     "num" : 3, 
     "avg" : 11 
     } 
    } 
] 

यदि यह मदद नहीं करता है, तो क्या आप अपना नक्शा फ़ंक्शन और दस्तावेज़ संरचना पोस्ट कर सकते हैं।

+0

धन्यवाद! अंत में उस कोड पर वापस जाने का समय था और इसे आजमाएं! –

संबंधित मुद्दे