Django के एनोटेट और कुल तरीकों के बीच अंतर?


114

Django के QuerySetदो तरीके हैं, annotateऔर aggregate। प्रलेखन का कहना है कि:

कुल () के विपरीत, एनोटेट () टर्मिनल क्लॉज नहीं है। एनोटेट () क्लॉज़ का आउटपुट एक क्वेरीसैट है।

क्या उनके बीच कोई और अंतर है? यदि नहीं, तो क्यों aggregateमौजूद है?

जवाबों:


186

मैं प्रलेखन से आपके उद्धरण के बजाय उदाहरण के प्रश्नों पर ध्यान केंद्रित करूंगा। संपूर्ण क्वेरी के Aggregateलिए मानों की गणना करता है । क्वेरी में प्रत्येक आइटम के लिए सारांश मानों की गणना करता है।Annotate

एकत्रीकरण

>>> Book.objects.aggregate(average_price=Avg('price'))
{'average_price': 34.35}

क्वेरी में सभी पुस्तकों की औसत कीमत वाला एक शब्दकोश देता है ।

टिप्पणी

>>> q = Book.objects.annotate(num_authors=Count('authors'))
>>> q[0].num_authors
2
>>> q[1].num_authors
1

q पुस्तकों की क्वेरी है, लेकिन प्रत्येक पुस्तक को लेखकों की संख्या के साथ एनोटेट किया गया है।


क्या मैं सही हूं कि .annotate()अकेले qs पर db हिट नहीं होता है, लेकिन कॉलिंग q[0].num_authorsकरता है? मुझे लगता है कि aggregateहमेशा db को हिट करना चाहिए क्योंकि यह एक टर्मिनल क्लॉज है?
अलियास ५१

@ alias51 जो वास्तव में मूल प्रश्न से संबंधित है, इसलिए मुझे नहीं लगता कि आठ साल पुराने प्रश्न पर टिप्पणियाँ पूछने के लिए सबसे अच्छी जगह है। यदि आप प्रश्न पूछना चाहते हैं, तो आप जांचconnection.queries सकते हैं । संकेत: जांचें कि क्या यह book = q[0]क्वेरी का कारण है या `book.num_authors` है।
अलसादेयर

21

यह मुख्य अंतर है, लेकिन समुच्चय भी एनोटेशन की तुलना में एक बड़े पैमाने पर काम करते हैं। एनोटेशन क्वेरी में अलग-अलग मदों से स्वाभाविक रूप से संबंधित होते हैं। यदि आप Countकई-से-कई फ़ील्ड की तरह कुछ पर एनोटेशन चलाते हैं , तो आपको क्वेरीसेट के प्रत्येक सदस्य (एक अतिरिक्त विशेषता के रूप में) के लिए एक अलग गणना मिलेगी। यदि आप एक एकत्रीकरण के साथ भी ऐसा ही करते हैं, हालांकि, यह क्वेरीसेट के प्रत्येक सदस्य पर हर रिश्ते को गिनने का प्रयास करेगा , यहां तक ​​कि डुप्लिकेट भी, और केवल एक मान के रूप में वापस करेगा।


क्या मैं सही हूं कि .annotate()अकेले qs ही db को हिट नहीं करता है, लेकिन एनोटेशन जैसे परिणाम को कॉल q[0].num_authorsकरता है? मुझे लगता है कि aggregateहमेशा db को हिट करना चाहिए क्योंकि यह एक टर्मिनल क्लॉज है?
अलियास ५१

21

सकल सकल एक पूरे क्वेरीसमूह से अधिक परिणाम (सारांश) मूल्यों उत्पन्न करते हैं। पंक्तियों से अलग मान प्राप्त करने के लिए पंक्तियों के ऊपर कार्य करें। (उदाहरण के लिए पंक्तियों में सभी मूल्यों का योग)। एग्रीगेट पूरे क्वेरीसेट पर लागू होता है और यह पूरे क्वेरीसेट पर परिणाम (सारांश) मान उत्पन्न करता है।

मॉडल में:

class Books(models.Model):
    name = models.CharField(max_length=100)
    pages = models.IntegerField()
    price = models.DecimalField(max_digits=5, decimal_places=3)

खोल में:

>>> Books.objects.all().aggregate(Avg('price'))
# Above code will give the Average of the price Column 
>>> {'price__avg': 34.35}

एनोटेट एनोटेट प्रत्येक ऑब्जेक्ट के लिए एक क्वेरी सारांश में एक स्वतंत्र सारांश उत्पन्न करता है। (हम कह सकते हैं कि यह क्वेरीरीट में प्रत्येक ऑब्जेक्ट को पुनरावृत्त कर सकता है और ऑपरेशन लागू कर सकता है)

मॉडल में:

class Video(models.Model):
    name = models.CharField(max_length=52, verbose_name='Name')
    video = models.FileField(upload_to=document_path, verbose_name='Upload 
               video')
    created_by = models.ForeignKey(User, verbose_name='Created by', 
                       related_name="create_%(class)s")
    user_likes = models.ManyToManyField(UserProfile, null=True, 
                  blank=True, help_text='User can like once', 
                         verbose_name='Like by')

दृश्य में:

videos = Video.objects.values('id', 'name','video').annotate(Count('user_likes',distinct=True)

देखने में यह प्रत्येक वीडियो के लिए पसंद की गणना करेगा


distinct=Trueअंतिम उदाहरण में क्यों आवश्यक है?
यूरी लियोनोव

@YuriyLeonov अलग = इसके लिए प्रयोग किया जाता है कि ऑपरेशन अलग मूल्य पर प्रदर्शन करता है। यह वर्तमान में पूछे गए प्रश्न से संबंधित नहीं है। इसके लिए खेद है कि वास्तव में मैंने अपने कोड का उपयोग किया है।
विनय कुमार
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.