2010-07-09 14 views
30

मुझे पता है कि मोंगो डीबी में कई क्षेत्रों द्वारा क्वेरी कैसे क्रमबद्ध करें, उदाहरण के लिए, db.coll.find().sort({a:1,b:-1})मोंगो जटिल सॉर्टिंग?

क्या मैं उपयोगकर्ता द्वारा परिभाषित फ़ंक्शन के साथ सॉर्ट कर सकता हूं; उदाहरण के लिए, ए और बी (a-b) के बीच अंतर से ए और बी पूर्णांक हैं?

धन्यवाद!

+1

मैं एक ही मुद्दे में चल रहा हूँ। क्या आप इसे सर्वर के पक्ष में पूरा करने के लिए एक रास्ता खोजने में सक्षम थे? मुझे वास्तव में क्लाइंट पर ऐसा करने की ज़रूरत नहीं है, या अतिरिक्त फ़ील्ड जोड़ें। –

उत्तर

29

अद्यतन: यह उत्तर पुराना प्रतीत होता है; ऐसा लगता है कि सॉर्टिंग से पहले इनपुट दस्तावेज़ों को बदलने के लिए $project function of the aggregation pipeline का उपयोग कर कस्टम सॉर्टिंग को कम से कम हासिल किया जा सकता है। @ एरी का उत्तर भी देखें।

मुझे नहीं लगता कि यह सीधे संभव है; sort documentation निश्चित रूप से कस्टम तुलना फ़ंक्शन प्रदान करने के किसी भी तरीके का उल्लेख नहीं करता है।

आप क्लाइंट में सॉर्ट करने से शायद सबसे अच्छे हैं, लेकिन यदि आप सर्वर पर ऐसा करने के लिए वास्तव में दृढ़ हैं, तो आप सर्वर पर सॉर्ट चलाने के लिए db.eval() का उपयोग करने में सक्षम हो सकते हैं (यदि आपका क्लाइंट इसका समर्थन करता है)।

सर्वर साइड प्रकार:

db.eval(function() { 
    return db.scratch.find().toArray().sort(function(doc1, doc2) { 
    return doc1.a - doc2.a 
    }) 
}); 

बराबर क्लाइंट साइड तरह बनाम:

db.scratch.find().toArray().sort(function(doc1, doc2) { 
    return doc1.a - doc2.b 
}); 

ध्यान दें कि यह भी एक aggregation pipeline के माध्यम से सॉर्ट करने के लिए संभव है और $orderby operator (यानी अलावा करने के लिए से .sort()) हालांकि इन तरीकों में से कोई भी आपको एक कस्टम सॉर्ट फ़ंक्शन प्रदान करने देता है।

+2

यूप। आगे खोदने के बाद मैंने पाया कि एक आरएफई दर्ज किया गया है ताकि सुविधा कार्यों को ठीक से करने की अनुमति दी जा सके। मुझे निश्चित रूप से मेरे ~ 10 मीटर दस्तावेज़ों के लिए 'toArray()' के दिखने को पसंद नहीं है, लेकिन यह स्पष्ट रूप से मामलों की स्थिति है। – gilesc

+0

हाय @ गिल्सक। क्या आप कृपया मुझे बताएं कि आपने वास्तव में 'आरएफई दायर' का विस्तार कैसे किया? मैं एक ही स्थिति में हूं। – LotusH

+1

@ वासबी मुझे लगता है कि वह इसका जिक्र कर रहा था: https://jira.mongodb.org/browse/SERVER-153 यह संभव नहीं है, लेकिन एक टिकट खुला है जहां वे इसे लागू करने पर विचार कर रहे हैं। लेकिन यह वर्षों से खुला रहा है, इसलिए सुनिश्चित नहीं है कि यह कभी होगा। – rmarscher

11

इस ऑपरेशन के साथ फ़ील्ड क्यों नहीं बनाते और इसे क्रमबद्ध क्यों करें?

+3

मुझे अभी भी ए और बी व्यक्तिगत रूप से पहुंच की आवश्यकता है। तो मुझे एक तीसरा क्षेत्र बनाना होगा। यह मेरे आवेदन के लिए काम करेगा, लेकिन एक सामान्य सिद्धांत वास्तव में खराब नीति होगी। मान लीजिए कि मेरे पास कई पूर्णांक फ़ील्ड थे, वहां व्युत्पन्न गुणों (ए-बी), (ए-सी), (ए-डी) का एक संयोजन विस्फोट होगा ... यहां तक ​​कि इस तरह के केवल एक फ़ील्ड के साथ, यह वास्तव में एक बड़े संग्रह के लिए अंतरिक्ष का अपर्याप्त है। मैं ऊपर उठ रहा हूं और यदि कोई और स्वीकार करने का उत्तर नहीं देता है, लेकिन एक बेहतर तरीका होना चाहिए। एसक्यूएल में यह 'चयन * से ऑर्डर द्वारा ऑर्डर करें (ए-बी) 'के रूप में आसान है। – gilesc

+1

ध्यान दें कि यद्यपि आप इसे SQL में कर सकते हैं, यह बहुत ही कुशल नहीं है। डेटाबेस को सभी ए और बी मान प्राप्त करना है, ए-बी की गणना करना, परिणामों को सॉर्ट करना और संबंधित रिकॉर्ड वापस करना है। मोंगो के साथ इसका मतलब यह होगा कि यदि आपके पास ए और बी पर कोई अनुक्रमणिका नहीं है तो सभी दस्तावेजों को स्मृति में लोड करना होगा। यदि आप कोई नया फ़ील्ड बनाते हैं, तो आप इस फ़ील्ड पर एक इंडेक्स बना सकते हैं, जो इस क्वेरी को वास्तव में तेज़ कर देगा। – konrad

+0

ग्रेट विचार। जब तक रिकॉर्ड की स्थिति का मूल्य रिकॉर्ड में डेटा के लिए स्थानीयकृत होता है, तो यह प्रविष्टि/अद्यतन पर सॉर्ट करने की लागत को पूरी तरह से कम करता है। – DoctorPangloss

15

इस में पड़ गए और यह है कि क्या मैं के साथ आया है:

db.collection.aggregate([ 
    { 
    $project: { 
     difference: { $subtract: ["$a", "$b"] } 
     // Add other keys in here as necessary 
    } 
    }, 
    { 
    $sort: { difference: -1 } 
    } 
]) 
संबंधित मुद्दे