按数组中元素的顺序匹配两个 jsonb 文档

Match two jsonb documents by order of elements in array

我在 postgres 中有 table 个数据 jsonb 文档,第二个 table 包含数据模板。

我需要仅按数组中元素的顺序以有效的方式将数据 jsonb 行与模板 jsonb 行匹配。

模板jsonb文件:

{
   "template":1,
   "rows":[
      "first row",
      "second row",
      "third row"
   ]
}

数据jsonb文件:

{
   "template":1,
   "data":[
      125,
      578,
      445
   ]
}

期望的输出:

Desc Amount
first row 125
second row 578
third row 445

模板table:

| id        | jsonb                                                  |
| --------  | ------------------------------------------------------ |
| 1         | {"template":1,"rows":["first row","second row","third row"]}           |
| 2         | {"template":2,"rows":["first row","second row","third row"]}           |
| 3         | {"template":3,"rows":["first row","second row","third row"]}           |

数据table:

| id        | jsonb                                         |
| --------  | -------------------------------------------   |
| 1         | {"template":1,"data":[125,578,445]}           |
| 2         | {"template":1,"data":[125,578,445]}           |
| 3         | {"template":2,"data":[125,578,445]}           |

我有数百万的数据jsonb文档和数百个模板。

我只是将两者都转换为 tables,然后使用 row_number 窗口函数,但对我来说这似乎不是很有效。

有更好的方法吗?

你必须规范化这个混乱的“on-the-fly”才能得到你想要的输出。

您需要使用 jsonb_array_elements() 取消嵌套每个数组,使用 with ordinality 选项获取数组索引。您可以通过提取 template 键的值来加入两个 table:

假设您想要 return 对数据中的特定行执行此操作 table:

select td.val, dt.val
from data 
  cross join jsonb_array_elements_text(data.jsonb_column -> 'data') with ordinality as dt(val, idx)
  left join template tpl 
         on tpl.jsonb_column ->> 'template' = data.jsonb_column ->> 'template'
  left join jsonb_array_elements_text(tpl.jsonb_column -> 'rows') with ordinality as td(val, idx) 
         on td.idx = dt.idx
where data.id = 1;

Online example