jsonb 可以按*值* 甚至部分值进行快速搜索吗?其他类型?

Ale*_*ani 7 postgresql database-design full-text-search json

我有一个person必须插入任意数据的表。由于我使用的是 Postgres 9.4,因此jsonb似乎是正确的选择。

示例数据:

id: 1, name: "Joe Doe", preferences: { color: "red" , toy: "car"}
id: 2, name: "Jane Doe", preferences: { color: "blue", food: "hamburguer" }
Run Code Online (Sandbox Code Playgroud)

问题是我需要通过变量值来查询它,例如:

所有在偏好上有“汉堡包”的人,部分查询也必须是可能的,所以搜索“b​​urg”必须给我带来记录2。

使用json函数,我可以搜索值,只要我知道key,对吗?或者有一种快速搜索值的方法?

我想做的是创建一个 tsvector 列并转储 json 以使用全文搜索来执行部分查询。

Erw*_*ter 6

对于Postgres 12或更高版本,请考虑 SQL/JSON 路径语言。看:


原始答案(对于旧版本)

我建议MATERIALIZED VIEW使用非嵌套值和三元组索引作为搜索工具。

hstore

如果您不需要嵌套值,hstore可能对您更好。使用该函数svals(hstore)取消嵌套hstore值。

您需要为hstore每个数据库安装一次附加模块:

CREATE EXTENSION hstore;
Run Code Online (Sandbox Code Playgroud)

桌子

CREATE TABLE person (
  person_id int PRIMARY KEY
, name text
, preferences jsonb
);
INSERT INTO person VALUES
  (1, 'Joe Doe', jsonb  '{"toy": "car", "color": "red"}')
, (2, 'Jane Doe', '{"food": "hamburguer", "color": "blue"}')
;
Run Code Online (Sandbox Code Playgroud)

物化视图

CREATE MATERIALIZED VIEW person_pref AS
SELECT p.person_id, j.preference        -- just pref
FROM   person p, svals(p.preferences) j(preference);
Run Code Online (Sandbox Code Playgroud)

这是CROSS JOIN LATERALset-returning function的隐式svals()

三元组索引

您需要为pg_trgm每个数据库安装一次附加模块:

CREATE EXTENSION pg_trgm;
Run Code Online (Sandbox Code Playgroud)

然后:

CREATE INDEX person_pref_trgm_idx ON person_pref
USING gin (preference gin_trgm_ops);
Run Code Online (Sandbox Code Playgroud)

细节:

询问

SELECT *
FROM   person p
WHERE  EXISTS (
   SELECT FROM person_pref pp
   WHERE  pp.person_id = p.person_id
   AND    pp.preference ILIKE '%burg%'
   );
Run Code Online (Sandbox Code Playgroud)

这对于选择性搜索词来说很快

jsonb

如果您有嵌套的 values 或numericbooleanvaluesjsonb可能会更有效。您可以执行与上述相同的操作jsonb_each_text(jsonb)

CREATE MATERIALIZED VIEW person_pref AS
SELECT p.person_id, j.preference
FROM  person p, jsonb_each_text(p.preferences) AS j(key, preference);
Run Code Online (Sandbox Code Playgroud)

相同的索引,相同的查询。

db<>在这里摆弄


归档时间:

查看次数:

4600 次

最近记录:

4 年,11 月 前