【问题标题】:How to annotate sum over Django JSONField (Array of objects) data?如何在 Django JSONField(对象数组)数据上注释总和?
【发布时间】:2021-11-02 05:23:33
【问题描述】:

我有这样的模型

# models.py
class MyModel( models.Model ):
    orders = models.JsonField(null= True, blank=True, default=list)
    category = models.ForeignKey(Category, on_delete=models.CASCADE)

我在这个结构中存储了json数据。

[
    {
        "order_name": "first order",
        "price": 200
    },
    {
        "order_name": "second order",
        "price": 800
    },
    {
        "order_name": "third order",
        "price": 100
    }
]

我想总结所有 json 对象的价格,即 200+800+100

【问题讨论】:

    标签: django django-3.0 django-postgresql django-aggregation django-jsonfield


    【解决方案1】:

    我没有使用过 JSONArrayField,但我做了一些研究,发现以下示例可以为您提供线索:

    MyModel.objects.annotate(
        order_price_sum=Sum(
            Cast(
                KeyTextTransform("price", "orders"), models.FloatField()
            )
        ),
    )
    

    我尝试将它应用于您的具体问题,您可以在以下链接中找到更多有用的信息:https://dev.to/saschalalala/aggregation-in-django-jsonfields-4kg5

    解决方法: 我试图弄清楚如何在 django 中使用 annotate 来管理 JSONArray,但它似乎没有很好的记录,所以我分享了这个解决方法来实现目标:

    total = 0
    for i in MyModel.objects.exclude(orders__isnull=True).values('orders'):
        total += sum([j.get('price',0) for j in i.get('orders') if j is not None])
    

    【讨论】:

    • 感谢@allexiusw 的回答,但此解决方案仅适用于单个 json 对象。我正在寻找 json 对象的数组。
    • 你试过了吗?我让 ORM 似乎以同样的方式与 json 对象和数组一起工作......它给了你一些类似的错误?
    • 以上代码返回
    • 你是对的,我所拥有的只是使用python代码来管理你所拥有的任务,如果你用annotate实现它,希望你分享答案。
    【解决方案2】:

    一种方法是使用jsonb_array_elements 将每个值分成几行,然后使用普通的聚合函数。

    例如:

    from django.db import models
    
    
    Model.objects.annotate(
        # This will break items into multiple rows
        annotate_field_1=models.Func(models.F('array_field__items'), function='jsonb_array_elements'),
    ).aggregate(
        # Then calculate the total.
        total=models.Count('annotate_field_1'),
    )['total']
    

    【讨论】:

    • Thaks @thenav56 但据我所知,UNNEST postgres 函数仅适用于 ArrayField,因为过滤 JsonField 数组在 django 中是灾难,我正在使用 JsonField 并将 json 对象数组存储在 JsonField 中。
    • 你试过jsonb函数jsonb_array_elementspostgresql.org/docs/9.5/functions-json.html吗?
    猜你喜欢
    • 2019-07-30
    • 1970-01-01
    • 2019-04-07
    • 2019-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-22
    • 2019-07-12
    相关资源
    最近更新 更多