如何使用 Postgres jsonb 搜索数组内的对象值?

fis*_*ben 4 arrays postgresql jsonb

我使用 PostgreSQL 9.5 和 JSONB 数据类型来存储文档。我的桌子是这样的:

create table records (
  id serial,
  data jsonb
);
Run Code Online (Sandbox Code Playgroud)

我的文档包含一系列对象,例如:

{
  "some_field": "a value",
  "another_field": 123,
  entries: [
    {
      "name": "John Doe",
      "age": 42
    },
    {
      "name": "Johnny McMuffin",
      "age": 117
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)

问题是我希望能够过滤数组name中的属性entries,但我无法弄清楚。我希望能够在表中找到与对象列表中的名称之一部分匹配的行。

我已经阅读了很多有关索引和表达式之类的内容,但我似乎无法让它发挥作用。这不应该是可能的吗?

小智 9

我不清楚预期的结果是什么,但这样的事情会起作用:

select r.id, e.*
from records r
  cross join lateral jsonb_array_elements(r.data -> 'entries') as e
where e ->> 'name' like '%Doe%';
Run Code Online (Sandbox Code Playgroud)

为了能够访问每个数组元素,您需要“取消嵌套”它们(即规范化非规范化文档)。请注意,上面的代码将为每个匹配的数组元素返回一行,而不是为表中的每一行返回一行。

如果您需要基表中唯一的完整行,您还可以将对名称的检查移至现有子查询:

select r.*
from records r
where exists (select 1 
             from jsonb_array_elements(r.data -> 'entries') as e
             where e ->> 'name' like '%Doe%');
Run Code Online (Sandbox Code Playgroud)

两个语句之间的区别在于,第一个查询只会显示匹配的数组元素。如果至少有一个匹配,第二个将显示文档的所有数组元素。