I have a model defined by
from django.contrib.postgres.fields import ArrayField
class Model(models.Model):
name = models.CharField(max_length=255)
tags = ArrayField(models.CharField(max_length=255))
I would like a way to efficiently grab the count of each distinct element in my tags ArrayField. I put together this piece of code to do try to do that.
Model.objects.annotate(elems=Func(F('tags'), function='unnest')).values_list('elems', flat=True).annotate(c=Count('elems'))
But it returns an error
...aggregate function calls cannot contain set-returning function calls
LINE 1: ...COUNT(unnest("...
^
HINT: You might be able to move the set-returning function into a LATERAL FROM item.
Any ideas on how to make this query work?
Edit
This is the SQL that Django's ORM generates.
SELECT unnest("model"."tags") AS "elems", COUNT(unnest("model"."tags")) AS "c" FROM "model" GROUP BY unnest("model"."tags");
This query worked for me:
select unnest(tags) as tag, count(tags) from model group by tag;
I think this ORM query gives the same result:
from django.db.models import Func, F, Count
Model.objects.annotate(tag=Func(F('tags'), function='unnest')).values('tag').order_by('tag').annotate(count=Count('id')).values_list('tag', 'count')
I have created the following table and populated with sample values:
create table model(
id serial primary key,
name text,
tags text[]
);
insert into model(name, tags) values ('a', array['a', 'b', 'c']);
insert into model(name, tags) values ('b', array['b', 'b', 'c']);
select unnest(tags) as tag, count(tags) from model group by tag;
+---+-----+
|tag|count|
+---+-----+
|c |2 |
|a |1 |
|b |3 |
+---+-----+
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With