Django JSONField Aggregate и Sum

У меня есть следующий JSON, сохраненный в БД PostgreSQL 9.4 и работающий под управлением Django 2.2

[{"rating": 6, "companyvalue_id": 188, "team_members_name": "pidofod tester", "users_teammember_id": 2793}, {"rating": 7, "companyvalue_id": 207, "team_members_name": "pidofod tester", "users_teammember_id": 2793}, {"rating": 4, "companyvalue_id": 207, "team_members_name": "xakir tester", "users_teammember_id": 2795}]

Имеется много записей в базе данных.

Я хотел бы объединить все экземпляры team_members_name и Sum, чтобы узнать общую сумму rating.

Данные JSON сохраняются в поле модели data = JSONField(null=True, blank=True)

Ближайший, который у меня есть -

def data_rating(self):
    model = apps.get_model('model', 'ModelName')
    model_count = model.objects.all()

    return model_count.objects.annotate(
        rating=Cast(
            KeyTextTransform("rating", "data"),
            IntegerField(),
        )
    ).values("rating").distinct().aggregate(Sum("rating"))["rating__sum"]

Вышеописанное работает только для одного объекта JSON, т.е. {"rating": 6, "companyvalue_id": 188, "team_members_name": "pidofod tester", "users_teammember_id": 2793}, однако мне нужно, чтобы KeyTextTransform работал для многих объектов JSON и во многих строках базы данных.

Мне также нужно фильтровать/агрегировать каждого пользователя, т.е. что такое "team_members_name": "pidofod tester" total rating Sum.

Конечным результатом является возврат этого результата в конечную точку DRF.

Пробовал много вариантов, как показано ниже, но ни один не работает или кажется близким, чувствую, что может потребоваться переделка модели. Любые идеи и предложения приветствуются!

    #return rating_tool_count.annotate(numbers_len=Func(F('rating_tool_data'), function='jsonb_array_length')).aggregate(rating_total=Sum(F("rating")))
    #return rating_tool_count.annotate(single_nested_value=F("rating_tool_data__team_members_name"),array_access=F("rating_tool_data__rating"),)

    #return rating_tool.objects.aggregate(Sum('rating_tool_data__rating')) #.values('rating_tool_data__rating').annotate(rating_total=Sum(Cast(KeyTextTransform("rating", "rating_tool_data"), models.IntegerField())))

    #return rating_tool_count.annotate(team_members_name=Cast(KeyTextTransform(
    #"team_members_name", "rating_tool_data"), models.TextField())).values("rating_tool_data").annotate(rating_total=Sum(Cast(KeyTextTransform("rating", "rating_tool_data"),
    #models.IntegerField())),).order_by("-rating_total")


    #return rating_tool_count.filter(rating_tool_data__name="pidofod tester").count()
    #return rating_tool_count.aggregate(Sum('rating_tool_data__rating'))
    #return rating_tool_count.aggregate(rating=Sum(Cast(KeyTextTransform("rating", "rating_tool_data"), models.IntegerField())))
    # return rating_tool_count.values('rating_tool_data__rating').annotate(rating_total=Sum('rating_tool_data__rating')).order_by('-rating_tool_data__rating')
    # return rating_tool_count.annotate(team_members_name=Cast(KeyTextTransform("team_members_name", "rating_tool_data"), models.TextField())).values("team_members_name").annotate(rating=Count("rating_tool_data"),ratings=Sum(Cast(KeyTextTransform("rating", "rating_tool_data"), models.IntegerField()))).order_by("-rating")

Попробуйте postgresql jsonb вместо json

jsonb позволяет эффективно извлекать значения в sql-запросах https://www.postgresql.org/docs/current/functions-json.html

также https://pganalyze.com/blog/postgres-jsonb-django-python может быть полезен

Вернуться на верх