django 在查询中计算相同字段值的最有效方法

发布于 2024-09-16 19:03:31 字数 1069 浏览 6 评论 0原文

假设我有一个包含很多字段的模型,但我只关心一个 charfield。可以说 charfield 可以是任何东西,所以我不知道可能的值,但我知道这些值经常重叠。所以我可以有 20 个带有“abc”的对象和 10 个带有“xyz”的对象,或者我可以有 50 个带有“def”的对象和 80 个带有“stu”的对象,我有 40000 个没有重叠的对象,我真的不关心。

如何有效地计数对象?我想要返回的是这样的:

{'abc': 20, 'xyz':10, 'other': 10,000}

或类似的东西,而不需要进行大量的 SQL 调用。

编辑:

我不知道是否有人会看到这个,因为我编辑它有点晚了,但是......

我有这个模型:

class Action(models.Model):
    author = models.CharField(max_length=255)
    purl = models.CharField(max_length=255, null=True)

从答案来看,我已经这样做了:

groups = Action.objects.filter(author='James').values('purl').annotate(count=Count('purl'))

但是......

这就是团体:(

{"purl": "waka"},{"purl": "waka"},{"purl": "waka"},{"purl": "waka"},{"purl": "mora"},{"purl": "mora"},{"purl": "mora"},{"purl": "mora"},{"purl": "mora"},{"purl": "lora"}

我只是用虚拟值填充了 purl)

我想要的是

{'waka': 4, 'mora': 5, 'lora': 1}

希望有人会看到这个编辑...

编辑2:

显然我的数据库(BigTable)不支持聚合函数 Django,这就是我遇到所有问题的原因。

Lets say if I have a model that has lots of fields, but I only care about a charfield. Lets say that charfield can be anything so I don't know the possible values, but I know that the values frequently overlap. So I could have 20 objects with "abc" and 10 objects with "xyz" or I could have 50 objects with "def" and 80 with "stu" and i have 40000 with no overlap which I really don't care about.

How do I count the objects efficiently? What I would like returned is something like:

{'abc': 20, 'xyz':10, 'other': 10,000}

or something like that, w/o making a ton of SQL calls.

EDIT:

I dont know if anyone will see this since I am editing it kind of late, but...

I have this model:

class Action(models.Model):
    author = models.CharField(max_length=255)
    purl = models.CharField(max_length=255, null=True)

and from the answers, I have done this:

groups = Action.objects.filter(author='James').values('purl').annotate(count=Count('purl'))

but...

this is what groups is:

{"purl": "waka"},{"purl": "waka"},{"purl": "waka"},{"purl": "waka"},{"purl": "mora"},{"purl": "mora"},{"purl": "mora"},{"purl": "mora"},{"purl": "mora"},{"purl": "lora"}

(I just filled purl with dummy values)

what I want is

{'waka': 4, 'mora': 5, 'lora': 1}

Hopefully someone will see this edit...

EDIT 2:

Apparently my database (BigTable) does not support the aggregate functions of Django and this is why I have been having all the problems.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

谁许谁一生繁华 2024-09-23 19:03:31

您想要类似于“count ... group by”的内容。您可以使用 django 的 ORM 的聚合功能来做到这一点:

from django.db.models import Count

fieldname = 'myCharField'
MyModel.objects.values(fieldname)
    .order_by(fieldname)
    .annotate(the_count=Count(fieldname))

关于此主题的先前问题:

You want something similar to "count ... group by". You can do this with the aggregation features of django's ORM:

from django.db.models import Count

fieldname = 'myCharField'
MyModel.objects.values(fieldname)
    .order_by(fieldname)
    .annotate(the_count=Count(fieldname))

Previous questions on this subject:

(り薆情海 2024-09-23 19:03:31

这称为聚合,Django 直接支持它

您可以通过过滤要计数的值、获取值列表并对它们进行计数来获得准确的输出,所有这些都在一组数据库调用中进行:

from django.db.models import Count
MyModel.objects.filter(myfield__in=('abc', 'xyz')).\
        values('myfield').annotate(Count('myfield'))

This is called aggregation, and Django supports it directly.

You can get your exact output by filtering the values you want to count, getting the list of values, and counting them, all in one set of database calls:

from django.db.models import Count
MyModel.objects.filter(myfield__in=('abc', 'xyz')).\
        values('myfield').annotate(Count('myfield'))
帥小哥 2024-09-23 19:03:31

您可以使用 Django 的 Count 聚合一个查询集来完成这个任务。像这样的事情:

from django.db.models import Count
queryset = MyModel.objects.all().annotate(count = Count('my_charfield'))
for each in queryset:
    print "%s: %s" % (each.my_charfield, each.count)

You can use Django's Count aggregation on a queryset to accomplish this. Something like this:

from django.db.models import Count
queryset = MyModel.objects.all().annotate(count = Count('my_charfield'))
for each in queryset:
    print "%s: %s" % (each.my_charfield, each.count)
羞稚 2024-09-23 19:03:31

除非您的字段值始终保证在特定情况下,否则在执行计数之前对其进行转换可能会很有用,即“apple”和“Apple”将被视为相同。

from django.db.models import Count
from django.db.models.functions import Lower

MyModel.objects.annotate(lower_title=Lower('title')).values('lower_title').annotate(num=Count('lower_title')).order_by('num')

Unless your field value is always guaranteed to be in a specific case, it may be useful to transform it prior to performing a count, i.e. so 'apple' and 'Apple' would be treated as the same.

from django.db.models import Count
from django.db.models.functions import Lower

MyModel.objects.annotate(lower_title=Lower('title')).values('lower_title').annotate(num=Count('lower_title')).order_by('num')
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文