在 PostgreSQL 中搜索 jsonb 数组
Searching jsonb array in PostgreSQL
我正在尝试在 PostgreSQL 9.4 中搜索 JSONB 对象。我的问题类似于 this thread.
但是我的数据结构略有不同,这导致了我的问题。我的数据结构是这样的:
[
{"id":1, "msg":"testing"}
{"id":2, "msg":"tested"}
{"id":3, "msg":"nothing"}
]
我想通过 msg(RegEx、LIKE、= 等)在该数组中搜索匹配的对象。更具体地说,我想要 table 中的所有行,其中 JSONB 字段的对象具有符合我的请求的 "msg"。
下面显示了一个类似于我的结构:
SELECT * FROM
(SELECT
'[{"id":1,"msg":"testing"},{"id":2,"msg":"tested"},{"id":3,"msg":"nothing"}]'::jsonb as data)
as jsonbexample;
这显示了对上述 link 的答案的尝试,但不起作用(returns 0 行):
SELECT * FROM
(SELECT
'[{"id":1,"msg":"testing"},{"id":2,"msg":"tested"},{"id":3,"msg":"nothing"}]'::jsonb as data)
as jsonbexample
WHERE
(data #>> '{msg}') LIKE '%est%';
谁能解释一下如何通过 JSONB 数组进行搜索?在上面的示例中,我想在 table 中找到任何行,其 "data" JSONB 字段包含一个对象,其中 "msg" 匹配某些内容(例如,LIKE '%est%')。
更新
此代码创建一个新类型(稍后需要):
CREATE TYPE AlertLine AS (id INTEGER, msg TEXT);
然后你可以用它来拆开列 JSONB_POPULATE_RECORDSET:
SELECT * FROM
JSONB_POPULATE_RECORDSET(
null::AlertLine,
(SELECT '[{"id":1,"msg":"testing"},
{"id":2,"msg":"tested"},
{"id":3,"msg":"nothing"}]'::jsonb
as data
)
) as jsonbex;
输出:
id | msg
----+---------
1 | testing
2 | tested
3 | nothing
并加入约束:
SELECT * FROM
JSONB_POPULATE_RECORDSET(
null::AlertLine,
(SELECT '[{"id":1,"msg":"testing"},
{"id":2,"msg":"tested"},
{"id":3,"msg":"nothing"}]'::jsonb
as data)
) as jsonbex
WHERE
msg LIKE '%est%';
输出:
id | msg
---+---------
1 | testing
2 | tested
所以剩下的部分问题是如何将它作为子句放在另一个查询中。
所以,如果上面代码的输出=x,我会怎么问:
SELECT * FROM mytable WHERE x > (0 rows);
您可以使用 exists
:
SELECT * FROM
(SELECT
'[{"id":1,"msg":"testing"},{"id":2,"msg":"tested"},{"id":3,"msg":"nothing"}]'::jsonb as data)
as jsonbexample
WHERE
EXISTS (SELECT 1 FROM jsonb_array_elements(data) as j(data) WHERE (data#>> '{msg}') LIKE '%est%');
查询 table 如下评论所述:
SELECT * FROM atable
WHERE EXISTS (SELECT 1 FROM jsonb_array_elements(columnx) as j(data) WHERE (data#>> '{msg}') LIKE '%est%');
我正在尝试在 PostgreSQL 9.4 中搜索 JSONB 对象。我的问题类似于 this thread.
但是我的数据结构略有不同,这导致了我的问题。我的数据结构是这样的:
[
{"id":1, "msg":"testing"}
{"id":2, "msg":"tested"}
{"id":3, "msg":"nothing"}
]
我想通过 msg(RegEx、LIKE、= 等)在该数组中搜索匹配的对象。更具体地说,我想要 table 中的所有行,其中 JSONB 字段的对象具有符合我的请求的 "msg"。
下面显示了一个类似于我的结构:
SELECT * FROM
(SELECT
'[{"id":1,"msg":"testing"},{"id":2,"msg":"tested"},{"id":3,"msg":"nothing"}]'::jsonb as data)
as jsonbexample;
这显示了对上述 link 的答案的尝试,但不起作用(returns 0 行):
SELECT * FROM
(SELECT
'[{"id":1,"msg":"testing"},{"id":2,"msg":"tested"},{"id":3,"msg":"nothing"}]'::jsonb as data)
as jsonbexample
WHERE
(data #>> '{msg}') LIKE '%est%';
谁能解释一下如何通过 JSONB 数组进行搜索?在上面的示例中,我想在 table 中找到任何行,其 "data" JSONB 字段包含一个对象,其中 "msg" 匹配某些内容(例如,LIKE '%est%')。
更新
此代码创建一个新类型(稍后需要):
CREATE TYPE AlertLine AS (id INTEGER, msg TEXT);
然后你可以用它来拆开列 JSONB_POPULATE_RECORDSET:
SELECT * FROM
JSONB_POPULATE_RECORDSET(
null::AlertLine,
(SELECT '[{"id":1,"msg":"testing"},
{"id":2,"msg":"tested"},
{"id":3,"msg":"nothing"}]'::jsonb
as data
)
) as jsonbex;
输出:
id | msg
----+---------
1 | testing
2 | tested
3 | nothing
并加入约束:
SELECT * FROM
JSONB_POPULATE_RECORDSET(
null::AlertLine,
(SELECT '[{"id":1,"msg":"testing"},
{"id":2,"msg":"tested"},
{"id":3,"msg":"nothing"}]'::jsonb
as data)
) as jsonbex
WHERE
msg LIKE '%est%';
输出:
id | msg
---+---------
1 | testing
2 | tested
所以剩下的部分问题是如何将它作为子句放在另一个查询中。
所以,如果上面代码的输出=x,我会怎么问:
SELECT * FROM mytable WHERE x > (0 rows);
您可以使用 exists
:
SELECT * FROM
(SELECT
'[{"id":1,"msg":"testing"},{"id":2,"msg":"tested"},{"id":3,"msg":"nothing"}]'::jsonb as data)
as jsonbexample
WHERE
EXISTS (SELECT 1 FROM jsonb_array_elements(data) as j(data) WHERE (data#>> '{msg}') LIKE '%est%');
查询 table 如下评论所述:
SELECT * FROM atable
WHERE EXISTS (SELECT 1 FROM jsonb_array_elements(columnx) as j(data) WHERE (data#>> '{msg}') LIKE '%est%');