仅刷新物化视图的一部分?

pfo*_*oti 7 postgresql

我的核心问题是我有一个 jsonb 数据库列,其中数据的形状如下:

{"ops": [
  {"insert": "yaaaah "},
  {"insert": {"atmention": {"id": "183"}}}, 
  {"insert": "  "},
  {"insert": {"hashtag": "potato"}},
  {"insert": " \n"}
]}
Run Code Online (Sandbox Code Playgroud)

(它是前端鹅毛笔字段的输出,我不想改变该结构)。目前,我的 API 注意到该字段有一个hashtag条目,并通过提取主题标签条目(在本例中为“马铃薯”)并更新存储标签的 text[] 列来手动刷新数据库中的标签列。然后我可以通过执行 查询匹配项@> tags,或通过 获取所有标签的列表select distinct unnest(tags) from documents

这是功能性的,但有些不令人满意,因为它使标签数据非规范化 - rich_text 列是权威值,但需要计算和更新标签列以进行查询。

我想我想做的是制作文档-标签对的物化视图,例如:

create materialized view hashtags
with taglist as (
  select documents.id, 
  jsonb_array_elements(rich_text->'ops') as ops from documents
) 
select 
  taglist.id,
  ops->'insert'->'hashtag'
from taglist 
where ops->'insert'->'hashtag' is not null;
Run Code Online (Sandbox Code Playgroud)

这是可行的,但现在每次更新、删除或插入文档时我都必须刷新物化视图,而且我认为这不会很好地扩展 - 因为它基本上需要顺序扫描每个文档。

我想知道是否有某种方法可以说,“嘿,通过删除 id = 1 的元素来刷新物化视图,然后重新运行 document.id = 1 的查询”。我会知道视图中的哪些条目可以更改,并且只想更改它们。

其他建议,例如有效索引此列的方法(这是一个具有单个顶级键“ops”的 jsonb 元素,其值始终是一个以“insert”作为顶级键的对象数组,该数组可能有一个欢迎使用文本或其他对象值,并且还可能具有与“插入”同级的“属性”顶级键)。

我的目标是将“此文档中有哪些主题标签”、“一般有哪些主题标签”和“哪些文档用马铃薯标记”查询的计算转移到 SQL 中,而不是使用我当前使用的非规范化技术(再次:函数,但有点不令人满意,因为这意味着我必须维护这个额外的列,并且可以想象数据会进入未定义的状态,就好像标记列以某种方式直接编辑,或者更新了 rich_text 字段而不重新计算标签栏)。

Dan*_*Dan 2

您可以创建“Lazy”或“Eager”物化视图。阅读有关它们的文章: 物化视图策略