0

概括:

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

背景:

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

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

在“管理员前端”中,我想支持管理员可以过滤(通过下拉菜单)以仅查看来自特定来源的日志。为此,我需要提取该origin字段的不同值。

考虑到日志数量在某些情况下可能在 1-10 百万范围内,我如何在 Django 中计算这组不同的值?

我已经尝试过的

  • 没什么,因为我不知道怎么做。

附加信息

  • 后端是用 Django 编写的,使用 Postgres 作为数据库。
  • 如果动态计算值不可行,我的替代方法是在日志滚动时连续构建一组不同的值。我认为这是第二种选择,因为它引入了额外的状态;如果可能的话,我更喜欢只计算/导出集合。
4

1 回答 1

1

执行所需选择的 QuerySet:

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

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


它的“有效性”是完全不同的主观问题。

PostgreSQL 需要查看所有记录来执行此选择。

一种可能性是仅在 JSON 的这一字段上添加索引(就像在这个SO question中一样)

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

于 2020-02-13T09:59:49.500 回答