Sql 获取最常用的多对多字段

Sql 获取最常用的多对多字段,sql,django,database,django-models,django-queryset,Sql,Django,Database,Django Models,Django Queryset,我有以下几种型号 class Tag(models.Model): name = models.CharField(max_length=30) # and other fields ... class Book(models.Model): name = models.CharField(max_length=140) tags = models.ManyToManyField(Tag, blank=True) # and other fields

我有以下几种型号

class Tag(models.Model):
    name = models.CharField(max_length=30)
    # and other fields ...

class Book(models.Model):
    name = models.CharField(max_length=140)
    tags = models.ManyToManyField(Tag, blank=True)
    # and other fields 

class Article(models.Model):
    name = models.CharField(max_length=140)
    tags = models.ManyToManyField(Tag, blank=True)
很少有其他模型像许多字段那样有标签。我想获得最常用的标记对象的列表。我试着从每个模型中筛选最常用的标签,然后从每个模型中获得前十名,并将它们与其他前十名相结合。我认为应该可以从“标记”模型本身中找到最常用的标记实例


除了我的方法之外,还有什么方法可以找到最常用的标记实例吗?非常感谢您的帮助。

图书型号中最常用的10个标签列表:

tags_of_book = Tag.objects.all().annotate(num_book = Count('book')).order_by('-num_book')[:10]

文章模型中最常用的10个标签列表:

tags_of_article = Tag.objects.all().annotate(num_article = Count('article')).order_by('-num_article')[:10]
您可以使用
annotate()
按标签在
文章中使用的时间量对标签进行排序(对于
书籍
,也可以这样做):


但是,要想在
文章
书籍
中找到最常用的标签,需要进行更多的查询,或者使用更高级的标签(请参见)

如果你想要
书籍
使用的前10个标签,那么你可以这样查询:

from django.db.models import Count

Tag.objects.annotate(
    nused=Count('book')
).order_by('-nused')[:10]
最后,我们将有一个
计数器
,其中包含这些标记的出现总数。但是请注意,由于我们每次都将数字限制为10

然后,我们可以通过从计数器获取最常用的标签来获取最常用的标签:

from operator import itemgetter

my_tags = map(itemgetter(0), ca.most_common(10))
如果我们使用上述方法生成前2名,那么我们将错过实际发生次数最多的
C
14次)

我们只需始终计算所有
标记
s,即可解决此问题,从而删除
[:10]
限制:

from collections import Counter
from django.db.models import Count

cntr = Counter()
for relation in Tag._meta.fields_map:
    cntr.update(
        {
            tg: tg.nr
            for tg in Tag.objects.annotate(nr=Count(relation)).order_by('nr')
        }
    )

所有这些元素中使用最多的标记对象?还是仅仅在一种元素中?后者更复杂(通常需要大量的查询),我想做的是在头版我想得到2篇文章,2本书和其他一些基于最常用标签的模型。因此,为了回答你的问题,我认为在所有这些元素中,标签对象使用最多。不幸的是,这会像一个更复杂的问题:两个计数都是相同的,文章的数量乘以书籍的数量。这是因为我们执行了双重连接,因此对同一本书进行了多次计数。您的解决方案就是我提出的。但如果我只想在所有地方使用前十个标签呢。我所做的是找到书籍、文章和其他模型的前十个标签,然后将它们结合起来,只得到前十个标签。我想要的是:目前,如果“python”标记只在“Book”中使用了50次。如果我在除“Book”之外的其他型号中搜索,则不会出现此标签。然而,因为它已经被使用了50次(比如说其他标签的数量小于50),所以当我搜索最常用的标签时,应该显示它。现在,如果在“文章”中根本不使用“python”标记,它将不会出现。非常感谢。这就是我要找的。
from operator import itemgetter

my_tags = map(itemgetter(0), ca.most_common(10))
Top Books    Top Articles
1. A (10)    1. D (12)
2. B (8)     2. E (8)
3. C (7)     3. C (7)
from collections import Counter
from django.db.models import Count

cntr = Counter()
for relation in Tag._meta.fields_map:
    cntr.update(
        {
            tg: tg.nr
            for tg in Tag.objects.annotate(nr=Count(relation)).order_by('nr')
        }
    )