如何在 Postgres 上的 Django 运行 中提取 JSONField 中特定键的所有不同值?

How do I extract all distint values for a specific key inside JSONField in Django running on Postgres?

总结:

对于下拉列表,我需要计算存储在 Postgres 数据库 table 中的 JSONField 中的特定键的不同值。最坏情况:table 包含 1-10 百万个条目。

背景:

我正在开发一个设置,其中我有多个部署(每个客户一个)。每个部署都包含一个后端和多个客户端。日志从客户端连续发布到后端。这些日志将包含一个字段 log_meta,其中包含一个名为 origin 的键,用于描述日志条目的来源。 origin 的值因客户而异,我不想对 origin 强制执行一组受限制的值,但通常它们表示客户所在的环境 运行; "DEV" 和 "PRODUCTION" 是 origin 的潜在值。实际上,在单个部署中 origin 可能只有 1-2 个不同的值。预计日志数量在1-1000万条之间。

from jsonfield import JSONField
from django.db import models

class Log(models.Model)
    # Other fields
    log_json = JSONField(default=list)
    log_meta: JSONField(default=dict) # Will contain a key named origin

在 "administrator frontend" 中,我想支持管理员可以过滤(通过下拉列表)以仅查看来自特定来源的日志。为此,我需要提取 origin 字段的不同值。

我如何在 Django 中计算这组不同的值,考虑到日志数量在某些情况下可能在 1 到 1000 万之间?

我已经尝试过的:

附加信息:

需要执行的 QuerySet select:

Log.objects.filter(
    # some filtering if required
    log_meta__origin__isnull=False
).order_by().values_list('log_meta__origin').distinct()

order_by() 用于清除 QuerySet 上已经存在的任何排序,以便我们稍后进行 distinct() 调用。


它的 'effectiveness' 是完全不同的主观问题。

PostgreSQL 需要查看所有记录才能执行此 select。

一种可能性是仅在 JSON 的这个字段上添加索引(如 SO question

由于这种类型的 select 看起来不需要经常执行(这意味着不同的来源非常稳定,您可以即缓存不同值的列表并定期更新它)- 使用 PostgreSQL Materialized Views 并定期/按需更新它们(或者简单地将列表存储在缓存 (Redis) 而不是物化视图中)。