यह वास्तव में (अभी भी) कई प्रश्नों द्वारा सबसे अच्छा संभाला जाता है, क्योंकि 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
में "सीमित" करने में सक्षम होंगे। तथ्य के बाद तीन को छोड़कर सभी को हटाने के बजाय सिर्फ तीन प्रविष्टियों के लिए।