Nil*_*lor 5 sql postgresql json nested
这是我的表格(简化的,只有重要的列):
CREATE TABLE things (
id serial primary key
, name varchar
, blueprint json default '{}'
);
Run Code Online (Sandbox Code Playgroud)
以及一些示例数据:
# select * from things;
id | name | blueprint
----+---------+-----------------------------------------------------------------------------
1 | Thing 1 | {}
2 | Thing 2 | {"1":{"name":"Iskapola","wight":"2"}}
3 | Thing 3 | {"1":{"name":"Azamund","weight":"3"}, "2":{"name":"Iskapola","weight":"1"}}
4 | Thing 4 | {"1":{"name":"Ulamir","weight":"1"}, "2":{"name":"Azamund","weight":"1"}}
Run Code Online (Sandbox Code Playgroud)
我想选择键'Azamund'下任意位置的行name。像这样的东西:
# select * from things where * ->> 'name' = 'Azamund';
id | blueprint
----+----------------------------------------------------------------------------
7 | {"1":{"name":"Azamund","weight":"3"}, "2":{"name":"Iskapola","weight":"1"}}
8 | {"1":{"name":"Ulamir","weight":"1"}, "2":{"name":"Azamund","weight":"1"}}
Run Code Online (Sandbox Code Playgroud)
数据的嵌套与示例中完全一样(只有一层)。
目前我们使用的是 PostgreSQL 9.3.5。
在 PostgreSQL 9.3 中可能吗?也许9.4?
您的查询已接近。json_each()是关键功能。或者jsonb_each()对于jsonb. 一些改进:
SELECT *
FROM things t
WHERE EXISTS (
SELECT FROM json_each(t.blueprint) b
WHERE b.value->>'name' ILIKE 'azamund'
);
Run Code Online (Sandbox Code Playgroud)
json_each()已经返回json值。不需要额外的演员。
更好的是,LATERAL使用EXISTS. 这比使用列表中的集合返回函数取消嵌套要干净得多SELECT。看:
用于ILIKE模式匹配。正则表达式匹配 ( ~, ~*) 更通用,但也更昂贵。因此,尽可能使用基本的LIKE/ 。ILKE看:
您已经看到了我对 JSON 数组的相关回答:
虽然嵌套 JSON 对象的查询看起来很简单,但数组有卓越的索引支持:
语法虽然复杂,但查询变得更简单、更高效。还可以使用以下形式的索引:
CREATE INDEX things_blueprint_gin_idx ON things USING gin (blueprint);
Run Code Online (Sandbox Code Playgroud)
CREATE INDEX things_blueprint_gin_idx ON things USING gin (blueprint);
Run Code Online (Sandbox Code Playgroud)
不区分大小写:
SELECT *
FROM things t
WHERE t.blueprint @? '$.* ? (@.name == "Azamund")';
Run Code Online (Sandbox Code Playgroud)
对于数组变体,我们还可以使用具有更高效的运算符类的索引jsonb_path_ops:
CREATE INDEX things_arr_foo_path_ops ON things_arr USING gin (blueprint jsonb_path_ops);
Run Code Online (Sandbox Code Playgroud)
SELECT *
FROM things t
WHERE t.blueprint @? '$.* ? (@.name like_regex "^azamund$" flag "i")';
Run Code Online (Sandbox Code Playgroud)
不区分大小写:
CREATE INDEX things_arr_foo_path_ops ON things_arr USING gin (blueprint jsonb_path_ops);
Run Code Online (Sandbox Code Playgroud)
db<>在这里摆弄
有关的:
| 归档时间: |
|
| 查看次数: |
6356 次 |
| 最近记录: |