如何计算queryset中对的频率

pbwdgjma  于 2021-08-09  发布在  Java
关注(0)|答案(1)|浏览(365)

我在django有两个模型:

class Pair(models.Model):
   pass

class Person(models.Model):
    pair = models.ForeignKey(to=Pair, related_name='mates')
    city = models.ForeignKey(to=City)

所以我需要计算不同城市的配对频率:

city_a<->city_b: 100
city_a<->city_a: 80
city_b<->city_c: 200
...

对于每个人,我可以通过以下方式获得对方的城市: person.pair.mates.exclude(id=person.id).first() 或者类似的,所以理论上我可以循环所有 Person 然后再计算频率,但显然这将是超低效的。
但我不知道如何通过标准查询集(如果有办法的话)获得这些信息。任何提示都欢迎

xyhw6mcr

xyhw6mcr1#

您可以注解这些对,例如:

from django.db.models import Count, F, Q

Person.objects.filter(
    Q(pair__mates__lt=F('pk')) | Q(pair__mates__gt=F('pk'))
).values(
    city1=F('city__name'),
    city2=F('pair__mates__city__name')
).annotate(
    number=Count('pk')
).order_by('city1', 'city2')

这个 __name 应该是你想使用的城市的一个领域。例如 __pk 可能也是一个选择。
查询的工作方式如下: Q(pair__mates__lt=F('pk')) | Q(pair__mates__gt=F('pk')) 通常应该排除“配偶”指的是相同的 Person . 然后我们使用 .values(..) 去拿 name (或其他文件)从城市和 pair__mates__city__names . 既然我们有了这两个值 Count(..) 每组数据的记录数 city1 以及 city2 . 这个 .order_by(..) 是避免订阅的必要条件,比如 qs[1] 将从原始记录中返回一条记录 Person 查询。
因此,查询如下所示:

SELECT app_name_city.name AS city1,
       T5.name AS city2,
       COUNT(app_name_person.id) AS number
FROM app_name_person
INNER JOIN app_name_pair ON app_name_person.pair_id = app_name_pair.id
INNER JOIN app_name_person T3 ON app_name_pair.id = T3.pair_id
INNER JOIN app_name_city ON app_name_person.city_id = app_name_city.id
INNER JOIN app_name_city T5 ON T3.city_id = T5.id
WHERE T3.id < app_name_person.id OR T3.id > app_name_person.id
GROUP BY app_name_city.name, T5.name
ORDER BY city1 ASC, city2 ASC

这将返回一个 QuerySet 词典数量:

<QuerySet [
    {'city1': 'city_a', 'city2': 'city_a', 'number': 80},
    {'city1': 'city_a', 'city2': 'city_b', 'number': 100},
    {'city1': 'city_b', 'city2': 'city_c', 'number': 200}
]>

相关问题