MongoDB
 sql >> डेटाबेस >  >> NoSQL >> MongoDB

अलग गिनती के आधार पर छाँटने के लिए मोंगो क्वेरी

यह वास्तव में (अभी भी) कई प्रश्नों द्वारा सबसे अच्छा संभाला जाता है, क्योंकि MongoDB के पास वास्तव में "अभी भी" ऐसा करने के लिए वास्तव में कुशल ऑपरेटर नहीं हैं।

हालांकि आप MongoDB 3.2 के साथ ऐसा कुछ कर सकते हैं, लेकिन स्पष्ट "कैच" हैं:

db.Books.aggregate([
    { "$group": {
        "_id": "$company",
        "count": { "$sum": 1 },
        "urls": {
            "$push": "$url"
        }
    }},
    { "$sort": { "count": -1 } },
    { "$limit": 10 },
    { "$project": {
        "count": 1,
        "urls": { "$slice": ["$urls",0, 3] }
    }}
])

और स्पष्ट समस्या यह है कि कुछ भी हो, आप अभी भी सभी . जोड़ रहे हैं समूहीकृत सरणी में "url" सामग्री का। इसमें 16 एमबी की बीएसओएन सीमा को पार करने की क्षमता है। ऐसा नहीं हो सकता है, लेकिन जब आप उनमें से केवल "तीन" चाहते हैं तो "सभी" सामग्री जोड़ना थोड़ा बेकार है।

तो फिर भी शीर्ष 10 परिणामों में से प्रत्येक पर अलग से "urls" के लिए केवल वास्तव में क्वेरी करना शायद अधिक व्यावहारिक है।

यहां नोड.जेएस के लिए एक सूची दी गई है जो दर्शाती है:

var async = require('async'),
    mongodb = require('mongodb'),
    MongoClient = mongodb.MongoClient;

MongoClient.connect("mongodb://localhost/test",function(err,db) {

    if (err) throw err;

    // Get the top 10
    db.collection("Books").aggregate(
        [
            { "$group": {
                "_id": "$company",
                "count": { "$sum": 1 }
             }},
             { "$sort": { "count": -1 } },
             { "$limit": 10 }
        ],function(err,results) {
            if (err) throw err;

            // Query for each result and map query response as urls
            async.map(
                results,
                function(result,callback) {
                    db.collection("Books").find({ 
                       "company": result.company 
                    }).limit(3).toArray(function(err,items) {
                        result.urls = items.map(function(item) { 
                            return item.url;
                        });
                        callback(err,result);
                    })
                },
                function(err,results) {
                    if (err) throw err;
                    // each result entry has 3 urls
                }
            );
        }
     )

});

हाँ, यह डेटाबेस के लिए अधिक कॉल है, लेकिन यह वास्तव में केवल दस . है और इसलिए वास्तव में कोई मुद्दा नहीं है।

असली इसके लिए समाधान SERVER-9377 - $push या $max को बढ़ाकर "top" संग्रह करने की अनुमति देता है "$समूह चरण में प्रति _id कुंजी के लिए N मान . इसे "प्रगति में" स्थिति का वादा किया गया है, इसलिए इस पर सक्रिय रूप से काम किया जा रहा है।

एक बार इसे हल करने के बाद, एक एकल एकत्रीकरण कथन व्यवहार्य हो जाता है, तब से आप परिणामी "यूआरएल" को प्रारंभिक $push में "सीमित" करने में सक्षम होंगे। तथ्य के बाद तीन को छोड़कर सभी को हटाने के बजाय सिर्फ तीन प्रविष्टियों के लिए।




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. मोंगोडीबी में ट्रेलो डेटा कैसे स्टोर करता है? (प्रति बोर्ड संग्रह?)

  2. एक असामान्य तरीके से मॉड्यूल.एक्सपोर्ट का उपयोग करना

  3. एक सरणी को सॉर्ट करें और MongoDB में एक रैंक फ़ील्ड जोड़ें

  4. पाइमोंगो के रेप्लिकासेट कनेक्शन का उपयोग करना:कभी-कभी इंडेक्स त्रुटि प्राप्त करना:कर्सर के लिए ऐसी कोई वस्तु नहीं है

  5. खोज क्वेरी में गणित का प्रदर्शन करें mongodb