首页 > 解决方案 > 使用 django ORM 查询对 jsondata-> 字段进行计数聚合

问题描述

我有一个模型

from jsonfield import JSONField
class data(model):
     content=JSONField()
     .......

我的模型数据示例数据库条目将是

data1   : id =1, content = {"email":"abc@gmail.com"}
data2   : id =2, content = {"email":"cdf@gmail.com"}
data3   : id =3,  content ={"email":"abc@gmail.com"}
data4   : id = 4, content ={"email":"sfg@gmail.com"}
data5   : id = 5, content ={"email":"abc@gmail.com"}
data6   : id = 6, content ={"email":"sfg@gmail.com"}

我需要找到非唯一的“电子邮件”值和 id 列表,例如

"abc@gmail.com"  :  [1,3,5]
"sfg@gmail.com   :  [4,6]

我正在使用 django 1.11 和 python 2.7 和 postgres9.3

我的查询是

lists = data.objects.filter(....).extra(select={'email':"content->>'email'"}).values('email','id')

我得到的结果是

{"email":"abc@gmail.com","id":1}
{"email":"cdf@gmail.com","id":2}
{"email":"abc@gmail.com","id":3}
{"email":"sfg@gmail.com","id":4}
{"email":"abc@gmail.com","id":5}
{"email":"sfg@gmail.com","id":6}

其中包括唯一和非唯一值,这不是必需的。

查询 1:是否可以使用 Django 仅从 JSON 字段中查询唯一值。

尝试过distinct() ,但在值部分中作为“id”和“email”都失败了

无论如何,将其进一步处理为

for d in lists:
    if d['email'] not in temp:
        temp[d['email']]=[d['id']]
    else:
        temp[d['email']].append(d['id'])

得到所有值的结果,包括唯一和非唯一值,如下所示

"abc@gmail.com"  :  [1,3,5]
"sfg@gmail.com"  :  [4,6]
"cdf@gmail.com"  :  [2] ## not desired

Query2:有没有什么方法可以更有效地处理这些数据?

标签: pythondjangopostgresql

解决方案


对于postgresqldjango >= 1.9,您可以尝试ArrayAgg。您的查询可能是这样的

lists = data.objects.filter(....).extra(select={'email':"content->>'email'"}).values('email','id').aggregate(list=ArrayAgg('id'))

推荐阅读