গণনা এবং গ্রুপ অনুসারে জাজানো সমতুল্য


91

আমার কাছে এমন একটি মডেল রয়েছে যা দেখতে দেখতে:

class Category(models.Model):
    name = models.CharField(max_length=60)

class Item(models.Model):
    name = models.CharField(max_length=60)
    category = models.ForeignKey(Category)

আমি প্রতিটি বিভাগের জন্য আইটেমের গণনা (কেবল গণনা) নির্বাচন করতে চাই, সুতরাং এসকিউএল এ এটি এত সহজ হবে:

select category_id, count(id) from item group by category_id

এই "জ্যাঙ্গো উপায়" করার সমতুল্য কি আছে? অথবা প্লেইন এসকিউএল একমাত্র বিকল্প? আমি জ্যাঙ্গোতে গণনা () পদ্ধতির সাথে পরিচিত , তবে আমি দেখতে পাচ্ছি না যে সেখানে গ্রুপ কীভাবে খাপ খায়।



@ সিরোস্যান্টিলি 巴拿馬 文件 六四 事件 法轮功 এটি কীভাবে নকল? এই প্রশ্নটি ২০০৮ সালে জিজ্ঞাসা করা হয়েছিল, এবং আপনি যেটির উল্লেখ করছেন সেটি ২ বছর পরে।
সের্গেই গোলভোচেনকো

বর্তমান sensক্যমত্যটি "গুণমান" দ্বারা বন্ধ হবে: < meta.stackexchange.com/questions/147643/… > যেহেতু "গুণমান" পরিমাপযোগ্য নয়, তাই আমি কেবল উন্নতমানের দ্বারা চলে যাই। ;-) সম্ভবত এটাই নেমে আসে যে শিরোনামে সেরা নবাগত গুগল কীওয়ার্ডগুলিতে কোন প্রশ্নটি আঘাত করে।
সিরো সান্তিলি 郝海东 冠状 病 六四 事件

উত্তর:


132

এখানে, যেমন আমি সবেমাত্র আবিষ্কার করেছি, কীভাবে জাজানো 1.1 সমষ্টিগত API এর মাধ্যমে এটি করা যায়:

from django.db.models import Count
theanswer = Item.objects.values('category').annotate(Count('category'))

4
জ্যাঙ্গোর বেশিরভাগ জিনিসের মতো, এগুলির
কোনওোটাই

4
নোট করুন যে ডিফল্ট ক্রম না order_by()হলে আপনাকে ব্যবহার করতে হবে 'category'। (ড্যানিয়েলের আরও ব্যাপক উত্তর দেখুন))
রিক ওয়েস্টেরায়

এটি কাজ করার কারণটি হ'ল কারণ .annotate()একটি এর পরে কিছুটা আলাদাভাবে কাজ করে.values() : "তবে, যখন ফলাফলের সেটগুলিতে ফিরে আসা কলামগুলি সীমাবদ্ধ করতে কোনও মান () ধারা ব্যবহার করা হয়, তখন টীকা মূল্যায়নের জন্য পদ্ধতিটি কিছুটা আলাদা। মূল ক্যোরিসেটে প্রতিটি ফলাফলের ফলাফল, মানগুলি () ধারাটিতে নির্দিষ্ট ক্ষেত্রগুলির অনন্য সংমিশ্রণ অনুসারে মূল ফলাফলগুলি শ্রেণিবদ্ধ করা হয়। "
mgalgs

58

( আপডেট : পূর্ণ ওআরএম সমষ্টি সমর্থনটি এখন জ্যাঙ্গো ১.১ এ অন্তর্ভুক্ত রয়েছে । প্রাইভেট এপিআই ব্যবহার সম্পর্কে নীচের সতর্কতার সাথে সত্য, এখানে নথিবদ্ধ পদ্ধতিটি আর জ্যাঙ্গোর ১.১ পোস্টের পরে সংস্করণে কাজ করে না; কেন আমি তা খোঁজতে খোঁজ করি নি; আপনি যদি ১.১ বা তার পরে থাকেন তবে আপনার উচিত যাইহোক সত্যিকারের সমষ্টিগত APIটি ব্যবহার করা উচিত ))

মূল একীকরণ সমর্থন ইতিমধ্যে 1.0 এ ছিল; এটি কেবল অনথিভুক্ত, অসমর্থিত এবং এর উপরে এখনও কোনও বন্ধুত্বপূর্ণ এপিআই নেই। তবে এখানে আপনি কীভাবে এটি ব্যবহার করতে পারবেন 1.1 আগমন না হওয়া পর্যন্ত (আপনার নিজের ঝুঁকিতে, এবং সম্পূর্ণ জ্ঞানে যে ক্যোয়ারী_গ্রুপ_বিযুক্তিটি কোনও পাবলিক এপিআইয়ের অংশ নয় এবং এটি পরিবর্তন হতে পারে):

query_set = Item.objects.extra(select={'count': 'count(1)'}, 
                               order_by=['-count']).values('count', 'category')
query_set.query.group_by = ['category_id']

আপনি যদি ক্যোয়ারী_সেটের মাধ্যমে পুনরাবৃত্তি করেন তবে প্রতিটি প্রত্যাবর্তিত মান একটি "বিভাগ" কী এবং "গণনা" কী সহ একটি অভিধান হবে।

আপনাকে এখানে হিসাবের মাধ্যমে অর্ডার দেওয়ার দরকার নেই, এটি কীভাবে হয়েছে তা প্রদর্শনের জন্য এটি অন্তর্ভুক্ত রয়েছে (এটি কোয়েসেট নির্মাণ শৃঙ্খলে অন্য কোথাও নয়, এক্সট্রা () কলটিতে করতে হবে)। এছাড়াও, আপনি গণনা (1) এর পরিবর্তে গণনা (আইডি) হিসাবে ভাল বলতে পারবেন, তবে পরবর্তীটি আরও কার্যকর হতে পারে।

এটিও নোট করুন যে .query.group_by সেট করার সময় মানগুলি অবশ্যই ডিজে কলামের নাম ('বিভাগ') নয় আসল ডিবি কলামের নাম ('শ্রেণি_ইড') হতে হবে। এর কারণ আপনি কোয়েরি অভ্যন্তরীণ পর্যায়ে এমন টুইট করছেন যেখানে সবকিছু ডিবি শর্তাবলী, জ্যাঙ্গো পদগুলিতে নয়।


পুরানো পদ্ধতির জন্য +1। এমনকি বর্তমানে অসমর্থিত হলেও, এটি কমপক্ষে বলতে বোধগম্য। আশ্চর্যজনক, সত্যিই।
এয়ারট্রাইক

ডকস.ডজ্যাঙ্গোপ্রজেক্ট / এএন / দেব / টোপিক্স / ডিবি / অ্যাসগ্রায়েশন /… এ অন্যান্য জটিল কাজগুলি করা যেতে পারে, সেখানে জাজানো সমষ্টিগত API এ একবার দেখুন , সেখানে আপনি কয়েকটি শক্তিশালী উদাহরণ পাবেন।
serfer2

@ সার্ফার 2 হ্যাঁ, এই দস্তাবেজগুলি ইতিমধ্যে এই উত্তরের শীর্ষ থেকে লিঙ্কযুক্ত।
কার্ল মায়ার

56

যেহেতু জ্যাঙ্গো ১.১ এর কাজগুলিতে গ্রুপিং করা সম্পর্কে আমি কিছুটা বিভ্রান্ত ছিলাম আমি ভেবেছিলাম আপনি কীভাবে এটি ব্যবহার করতে যাচ্ছেন সে সম্পর্কে আমি এখানে বিশদভাবে বর্ণনা করব। প্রথমে মাইকেল যা বলেছিলেন তার পুনরাবৃত্তি:

এখানে, যেমন আমি সবেমাত্র আবিষ্কার করেছি, কীভাবে জাজানো 1.1 সমষ্টিগত API এর মাধ্যমে এটি করা যায়:

from django.db.models import Count
theanswer = Item.objects.values('category').annotate(Count('category'))

আপনার প্রয়োজন যে নোট from django.db.models import Count!

এটি কেবল বিভাগগুলি নির্বাচন করবে এবং তারপরে একটি টীকা যুক্ত করবে category__count। ডিফল্ট ক্রম উপর নির্ভর করে এটি আপনার প্রয়োজন হতে পারে তবে ডিফল্ট ক্রমটি যদি এই ক্ষেত্র ব্যতীত অন্য কোনও ক্ষেত্র ব্যবহার করে categoryতবে তা কাজ করবে না । এর কারণ হ'ল অর্ডার দেওয়ার জন্য প্রয়োজনীয় ক্ষেত্রগুলিও নির্বাচিত এবং প্রতিটি সারি অনন্য করে তুলেছে, যাতে আপনি কীভাবে স্টাফগুলিকে গোষ্ঠীভুক্ত করবেন না। এটি ঠিক করার একটি দ্রুত উপায় হ'ল অর্ডারটি পুনরায় সেট করা:

Item.objects.values('category').annotate(Count('category')).order_by()

এটি আপনার পছন্দসই ফলাফল উত্পন্ন করবে। টীকাটির নাম সেট করতে আপনি ব্যবহার করতে পারেন:

...annotate(mycount = Count('category'))...

তারপরে mycountফলাফলগুলিতে আপনার কাছে একটি টিকা দেওয়া হবে ।

গ্রুপিং সম্পর্কে অন্যান্য সমস্ত বিষয় আমার কাছে খুব সোজা ছিল। আরও বিশদ তথ্যের জন্য জ্যাঙ্গো সমষ্টি এপিআই পরীক্ষা করে দেখুন Be


4
। কর্ম একই সেট ( 'category__category') বিদেশী কী ক্ষেত্র Item.objects.values উপর সম্পাদন করতে annotate (COUNT ( 'category__category')) order_by ()।
মিউট্যান্ট

ডিফল্ট ক্রম ক্ষেত্র কী তা কীভাবে নির্ধারণ করা হয়?
বোগাতিয়ার

2

এটা কেমন? (ধীর ছাড়া অন্য।)

counts= [ (c, Item.filter( category=c.id ).count()) for c in Category.objects.all() ]

এটি সংক্ষিপ্ত হওয়ার সুবিধা রয়েছে, এমনকি যদি এটি প্রচুর সারি নিয়ে আসে।


সম্পাদনা করুন

একটি ক্যোয়ারী সংস্করণ। বিটিডাব্লু, এটি প্রায়শই ডাটাবেজে নির্বাচন করুন (*) এর চেয়ে দ্রুত । এটি দেখতে চেষ্টা করুন।

counts = defaultdict(int)
for i in Item.objects.all():
    counts[i.category] += 1

এটি দুর্দান্ত এবং সংক্ষিপ্ত, তবে আমি প্রতিটি বিভাগের জন্য পৃথক ডাটাবেস কল এড়াতে চাই।
সের্গেই গোলভোচেনকো

এটি সহজ ক্ষেত্রেগুলির জন্য সত্যই একটি ভাল পদ্ধতি। আপনার যখন একটি বড় ডেটাসেট থাকবে তখন এটি নীচে নেমে আসে এবং আপনি কোনও সংখ্যা ছাড়াই থাকা ডেটা টেনে না রেখে একটি গণনা অনুযায়ী + সীমা (অর্থাত্ প্যাগিনেট) অর্ডার করতে চান।
কার্ল মেয়ার 16

@ কার্ল মেয়ার: সত্য - এটি একটি বড় ডেটাসেটের জন্য কুকুর হতে পারে; তবে আপনার এটি নিশ্চিত হওয়ার জন্য আপনার বেঞ্চমার্ক করা দরকার। এছাড়াও, এটি অসমর্থিত স্টাফগুলির উপরও নির্ভর করে না; অসমর্থিত বৈশিষ্ট্যগুলি সমর্থন না করা পর্যন্ত এটি অন্তর্বর্তী সময়ে কাজ করে।
এস। লট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.