2013-12-08 5 views
13

मैं मोंगोडीबी एकत्रीकरण के लिए नया हूं और सोच रहा हूं कि मोंगोडीबी एकत्रीकरण ढांचे का उपयोग करके मध्यस्थ की गणना करने का कोई तरीका है या नहीं?मोंगोडीबी समेकन ढांचे में औसत की गणना करें

चीयर्स,

लुईस

+0

AFAIK वहाँ ऐसी कोई बात नहीं के रूप में '$ median' तो शायद आप का उपयोग करना होगा इस के लिए नक्शे-को कम है। – hgoebl

+0

'$ median' संचयक के लिए समर्थन जोड़ने के लिए एक खुली सुविधा अनुरोध है। मोंगोडीबी मुद्दे ट्रैकर में कृपया ऊपर/देखें [सेवर -4929] (https://jira.mongodb.org/browse/SERVER-4929)। – Stennie

उत्तर

2

एकत्रीकरण ढांचे मंझला का समर्थन नहीं करता आउट-ऑफ-द-बॉक्स। तो आपको अपने आप कुछ लिखना होगा।

मैं आपको एप्लिकेशन स्तर पर ऐसा करने की सलाह दूंगा। सामान्य खोज() के साथ अपने सभी दस्तावेज़ों को पुनर्प्राप्त करें, परिणाम सेट को सॉर्ट करें (या तो कर्सर के .sort() फ़ंक्शन का उपयोग करके या एप्लिकेशन में उन्हें सॉर्ट करने के द्वारा डेटाबेस पर) और उसके बाद तत्व size/2 प्राप्त करें।

जब आप वास्तव में डेटाबेस स्तर पर ऐसा करना चाहते हैं, तो आप इसे मानचित्र-कम करने के साथ कर सकते हैं। नक्शा-फ़ंक्शन कुंजी और एक सरणी को एक मान के साथ उत्सर्जित करेगा - वह मान जिसे आप मध्यस्थ प्राप्त करना चाहते हैं। कम-फ़ंक्शन केवल प्राप्त परिणामों के सरणी को जोड़ देगा, इसलिए प्रत्येक कुंजी सभी मानों के साथ सरणी के साथ समाप्त होती है। अंतिमकरण-फ़ंक्शन फिर उस सरणी के मध्य को गणना करेगा, फिर सरणी को सॉर्ट करके और फिर तत्व संख्या size/2 प्राप्त करें।

+0

ठीक है कि शानदार है, मैं इसे जाने दूंगा। – user3080286

20

औसत सामान्य मामले में गणना करने के लिए औसत कुछ मुश्किल है, क्योंकि इसमें पूरे डेटा सेट को सॉर्ट करना शामिल है, या एक गहराई के साथ एक पुनरावर्तन का उपयोग करना जो डेटा सेट आकार के समान है। यही कारण है कि कई डेटाबेस में बॉक्स के बाहर मध्यस्थ ऑपरेटर नहीं होता है (MySQL में कोई भी नहीं है)।

मंझला इन दो बयानों के साथ किया जाएगा गणना करने के लिए सबसे आसान तरीका है (विशेषता यह सोचते हैं जिस पर हम मंझला गणना करने के लिए चाहते हैं a कहा जाता है और हम इस पर चाहते हैं संग्रह में सभी दस्तावेजों, coll):

count = db.coll.count(); 
db.coll.find().sort({"a":1}).skip(count/2 - 1).limit(1); 

यह suggest for MySQL लोगों के बराबर है।

+5

मुझे पता है कि इसे धन्यवाद देने के लिए टिप्पणी करने की अनुमति नहीं है .. लेकिन यह सुंदर है :) – fguillen

1

कुल ढांचे के साथ एक शॉट में ऐसा करना संभव है।

सॉर्ट करें => ऐरे सॉर्ट किए गए मानों में डालें => सरणी का आकार प्राप्त करें => विभाजन को दो से विभाजित करें => विभाजन का अंतर मान (मध्यस्थ के बाएं तरफ) => बायीं तरफ 1 जोड़ें (दाईं तरफ) =

मॉडल है लेखक की प्रवेश ("मालिक के साथ पुस्तक की एक सूची:> बाईं ओर और सही पक्ष पर सरणी तत्व प्राप्त => दो तत्वों की औसत

यह वसंत जावा mongoTemplate के साथ एक नमूना है "), उद्देश्य उपयोगकर्ताओं द्वारा पुस्तक का औसत प्राप्त करना है:

 GroupOperation countByBookOwner = group("owner").count().as("nbBooks"); 

    SortOperation sortByCount = sort(Direction.ASC, "nbBooks"); 

    GroupOperation putInArray = group().push("nbBooks").as("nbBooksArray"); 

    ProjectionOperation getSizeOfArray = project("nbBooksArray").and("nbBooksArray").size().as("size"); 

    ProjectionOperation divideSizeByTwo = project("nbBooksArray").and("size").divide(2).as("middleFloat"); 

    ProjectionOperation getIntValueOfDivisionForBornLeft = project("middleFloat", "nbBooksArray").and("middleFloat") 
      .project("trunc").as("beginMiddle"); 

    ProjectionOperation add1ToBornLeftToGetBornRight = project("beginMiddle", "middleFloat", "nbBooksArray") 
      .and("beginMiddle").project("add", 1).as("endMiddle"); 

    ProjectionOperation arrayElementAt = project("beginMiddle", "endMiddle", "middleFloat", "nbBooksArray") 
      .and("nbBooksArray").project("arrayElemAt", "$beginMiddle").as("beginValue").and("nbBooksArray") 
      .project("arrayElemAt", "$endMiddle").as("endValue"); 

    ProjectionOperation averageForMedian = project("beginMiddle", "endMiddle", "middleFloat", "nbBooksArray", 
      "beginValue", "endValue").and("beginValue").project("avg", "$endValue").as("median"); 

    Aggregation aggregation = newAggregation(countByBookOwner, sortByCount, putInArray, getSizeOfArray, 
      divideSizeByTwo, getIntValueOfDivisionForBornLeft, add1ToBornLeftToGetBornRight, arrayElementAt, 
      averageForMedian); 

    long time = System.currentTimeMillis(); 
    AggregationResults<MedianContainer> groupResults = mongoTemplate.aggregate(aggregation, "book", 
      MedianContainer.class); 

और यहाँ जिसके परिणामस्वरूप एकत्रीकरण:

{ 
"aggregate": "book" , 
"pipeline": [ 
    { 
     "$group": { 
      "_id": "$owner" , 
      "nbBooks": { 
       "$sum": 1 
      } 
     } 
    } , { 
     "$sort": { 
      "nbBooks": 1 
     } 
    } , { 
     "$group": { 
      "_id": null , 
      "nbBooksArray": { 
       "$push": "$nbBooks" 
      } 
     } 
    } , { 
     "$project": { 
      "nbBooksArray": 1 , 
      "size": { 
       "$size": ["$nbBooksArray"] 
      } 
     } 
    } , { 
     "$project": { 
      "nbBooksArray": 1 , 
      "middleFloat": { 
       "$divide": ["$size" , 2] 
      } 
     } 
    } , { 
     "$project": { 
      "middleFloat": 1 , 
      "nbBooksArray": 1 , 
      "beginMiddle": { 
       "$trunc": ["$middleFloat"] 
      } 
     } 
    } , { 
     "$project": { 
      "beginMiddle": 1 , 
      "middleFloat": 1 , 
      "nbBooksArray": 1 , 
      "endMiddle": { 
       "$add": ["$beginMiddle" , 1] 
      } 
     } 
    } , { 
     "$project": { 
      "beginMiddle": 1 , 
      "endMiddle": 1 , 
      "middleFloat": 1 , 
      "nbBooksArray": 1 , 
      "beginValue": { 
       "$arrayElemAt": ["$nbBooksArray" , "$beginMiddle"] 
      } , 
      "endValue": { 
       "$arrayElemAt": ["$nbBooksArray" , "$endMiddle"] 
      } 
     } 
    } , { 
     "$project": { 
      "beginMiddle": 1 , 
      "endMiddle": 1 , 
      "middleFloat": 1 , 
      "nbBooksArray": 1 , 
      "beginValue": 1 , 
      "endValue": 1 , 
      "median": { 
       "$avg": ["$beginValue" , "$endValue"] 
      } 
     } 
    } 
] 

}

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