如何在 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 万之间?
我已经尝试过的:
- 没什么,因为我不知道该怎么做。
附加信息:
- 后端用 Django 编写,使用 Postgres 作为数据库。
- 如果即时计算值不可行,我的替代方法是在日志滚动时连续构建一组不同的值。我认为这是第二个选项,因为它引入了额外的状态;如果可能的话,我更喜欢 compute/derive 集合。
需要执行的 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) 而不是物化视图中)。
总结:
对于下拉列表,我需要计算存储在 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 万之间?
我已经尝试过的:
- 没什么,因为我不知道该怎么做。
附加信息:
- 后端用 Django 编写,使用 Postgres 作为数据库。
- 如果即时计算值不可行,我的替代方法是在日志滚动时连续构建一组不同的值。我认为这是第二个选项,因为它引入了额外的状态;如果可能的话,我更喜欢 compute/derive 集合。
需要执行的 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) 而不是物化视图中)。