这是我的表格(简化的,只有重要的列):
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"}} …
Run Code Online (Sandbox Code Playgroud) 我的数据示例如下所示:
{"city": "NY",
"skills": [
{"soft_skills": "Analysis"},
{"soft_skills": "Procrastination"},
{"soft_skills": "Presentation"}
],
"areas_of_training": [
{"areas of training": "Visio"},
{"areas of training": "Office"},
{"areas of training": "Risk Assesment"}
]}
Run Code Online (Sandbox Code Playgroud)
我想运行一个查询来查找具有 soft_skills 的用户,Analysis
并且可能运行另一个查询来查找其培训领域是Visio
和Risk Assesment
我的列类型是jsonb
. 如何在这些深度嵌套的对象上实现搜索查询?城市工程一级查询使用SELECT * FROM mydata WHERE content::json->>'city'='NY';
我如何还可以使用 LIKE 关键字或字符串匹配来运行深度嵌套值的匹配?
我尝试设置 GIN 索引,但我认为在运行请求时没有使用我的索引,无论是使用运算符还是函数。
在我们的表中,我们有一个json_aip
包含 Json的 JSONB 字段 ( ),如下所示:
{
"properties": {
"pdi": {
"contextInformation": {
"tags": ["SOME_TAG"]
},
},
}
Run Code Online (Sandbox Code Playgroud)
表创建:
create table t_aip (
json_aip jsonb,
[...]
);
CREATE INDEX idx_aip_tags
ON t_aip
USING gin ((json_aip -> 'properties' -> 'pdi' -> 'contextInformation' -> 'tags'));
Run Code Online (Sandbox Code Playgroud)
我们不能?|
像使用 JDBC 一样使用运算符。但是有传言说当我运行这种类型的查询时我应该看到我的索引。
EXPLAIN ANALYZE SELECT count(*)
FROM storage.t_aip
WHERE json_aip#>'{properties,pdi,contextInformation,tags}' ?| array['SOME_TAG']
Run Code Online (Sandbox Code Playgroud)
结果:
Aggregate
(cost=27052.16..27052.17 rows=1 width=8) (actual time=488.085..488.087 rows=1 loops=1)
-> Seq Scan on t_aip (cost=0.00..27052.06 …
Run Code Online (Sandbox Code Playgroud) 参考原始的stackoverflow问题,我试图将金币索引应用于Postgres 9.4中数组对象中的键,但我没有得到第一个答案中所述的结果.
你能否解决这个错误?
我遵循的步骤如下.
第1部分:创建表和索引
CREATE TABLE tracks (id serial, artists jsonb);
CREATE INDEX tracks_artists_gin_idx ON tracks USING gin (artists);
INSERT INTO tracks (id, artists) VALUES (1, '[{"name": "blink-182"}]');
INSERT INTO tracks (id, artists) VALUES (2, '[{"name": "The Dirty Heads"}, {"name": "Louis Richards"}]');
Run Code Online (Sandbox Code Playgroud)
第2部分:查询
SELECT * FROM tracks WHERE artists @> '{"name": "The Dirty Heads"}';
id | artists
----+---------
(0 rows)
Run Code Online (Sandbox Code Playgroud)
此查询提供空结果.
我也尝试使用jsonb_path_ops
GIN索引.
替代索引和查询:
DROP INDEX tracks_artists_gin_idx;
CREATE INDEX tracks_artistnames_gin_idx ON tracks USING gin (artists jsonb_path_ops); …
Run Code Online (Sandbox Code Playgroud) 假设我有下parents
表:
create table parents (
id integer not null constraint parents_pkey primary key,
name text not null,
children jsonb not null
);
Run Code Online (Sandbox Code Playgroud)
其中children
有一个如下结构的json数组:
[
{
"name": "child1",
"age": 10
},
{
"name": "child2",
"age": 12
}
]
Run Code Online (Sandbox Code Playgroud)
例如,我需要找到所有有 10 岁到 12 岁孩子的父母。
我创建以下查询:
select distinct
p.*
from
parents p, jsonb_array_elements(p.children) c
where
(c->>'age')::int between 10 and 12;
Run Code Online (Sandbox Code Playgroud)
当表parents
很大时(例如 1M 条记录),它工作得很好,但速度很慢。我尝试在children
字段上使用“杜松子酒”索引,但这没有帮助。
那么有没有办法加快此类查询的速度呢?或者也许还有另一种解决方案可以对嵌套 json 数组中的字段进行查询/索引?
查询计划:
Unique (cost=1793091.18..1803091.18 …
Run Code Online (Sandbox Code Playgroud) 我有一个表users
有一个jsonb
叫场data
。我必须检索在该列中具有与给定字符串匹配的值的所有用户data
。例如:
user1 = data: {"property_a": "a1", "property_b": "b1"}
user2 = data: {"property_a": "a2", "property_b": "b2"}
Run Code Online (Sandbox Code Playgroud)
我想检索具有data
匹配值的任何用户'b2'
,在本例中为'user2'
.
知道如何以优雅的方式做到这一点吗?我可以检索所有data
用户的所有密钥并手动创建查询,但这既不快速也不优雅。
此外,我必须检索匹配的键和值,但首先要做的是。
我有一个json数组,其中包含大约1000个结构元素"oid:aaa,instance:bbb,value:ccc".
{"_id": 37637070
, "data": [{"oid": "11.5.15.1.4", "value": "1", "instance": "1.1.4"}
, {"oid": "11.5.15.1.9", "value": "17", "instance": "1.1.4"}
, {"oid": "12.5.15.1.5", "value": "0.0.0.0", "instance": "0"}]}
Run Code Online (Sandbox Code Playgroud)
oid
并且instance
每个json数组都是唯一的.如果我有权更改结构,我会将格式更改为key:value:
{"11.5.15.1.4-1.1.4":"1", "11.5.15.1.9-1.1.4": "17", "12.5.15.1.5-0": "0.0.0.0"}
Run Code Online (Sandbox Code Playgroud)
但是,如果我需要留在旧结构
oid
从阵列中获取特定的最快方法是什么?
什么是得到一个表的3列最快的方式oid
,instance
和value
.或者更好的是使用oid + instance作为列标题的数据透视表.
对于2.我尝试了以下内容,但在一张大桌子上它很慢:
select *
from (
select a->>'oid' oid, a->>'instance' instance, a->>'value' value1, id
from (
select jsonb_array_elements(config#>'{data}') a, id
from configuration
) b
) c
where oid = '1.3.6.1.4.1.7352.3.10.2.5.35.3' and instance = …
Run Code Online (Sandbox Code Playgroud) 在 users 表中,我有一个 jsob 列experience
,其 json 结构如下:
[
{
"field": "devops",
"years": 9
},
{
"field": "backend dev",
"years": 7
}
... // could be N number of objects with different values
]
Run Code Online (Sandbox Code Playgroud)
业务需求
客户可以要求在任何领域有经验的人员以及在每个领域各自有多年的经验
这是一个示例查询
SELECT * FROM users
WHERE
jsonb_path_exists(experience, '$[*] ? (@.field == "devops" && @.years > 5)') and
jsonb_path_exists(experience, '$[*] ? (@.field == "backend dev" && @.years > 5)')
LIMIT 3;
Run Code Online (Sandbox Code Playgroud)
假设我收到请求
[
{ field: "devops", years: 5 },
{ field: "java", years: …
Run Code Online (Sandbox Code Playgroud) 有两个表:
授权联系人(auth_contacts
):
(
userid varchar
contacts jsonb
)
Run Code Online (Sandbox Code Playgroud)
contacts
包含具有属性的联系人数组 {contact_id, type}
discussion
:
(
contact_id varchar
discussion_id varchar
discussion_details jsonb
)
Run Code Online (Sandbox Code Playgroud)
该表auth_contacts
至少有100k记录,因此非JSONB类型是不合适的,因为它会使记录数量增加一倍或三倍.
示例数据auth_contacts
:
userid | contacts
'11111' | '{"contact": [{"type": "type_a", "contact_id": "1-A-12"}
, {"type": "type_b", "contact_id": "1-A-13"}]}'
Run Code Online (Sandbox Code Playgroud)
discussion
表有500万条奇迹.
我想加入discussion.contact_id
(关系列)与联系人id,json对象在json对象的数组中auth_contacts.contacts
.
一种非常粗暴的方式是:
SELECT *
FROM discussion d
JOIN (SELECT userid, JSONB_OBJECT_KEYS(a.contacts) AS auth_contact
FROM auth_contacts a) AS contacts
ON (d.contact_id = contacts.auth_contact::text)
Run Code Online (Sandbox Code Playgroud)
这样做实际上是在运行时创建(内部sql)用户ID与联系人id表(这是我正在避免的,因此用于JSONB数据类型对于具有大记录的用户的此查询需要26 +秒,这并非全是好的.其他一些方法:PostgreSQL 9.4:在数组内的JSON字段id上的Aggregate/Join表
但应该有一个更简洁的更好的方式,就像JOIN一样简单.d.contact_id = …
在我的 PostgreSQL 11.11 中,我有一列jsonb
保存如下对象:
{
"dynamicFields":[
{
"name":"200",
"hidden":false,
"subfields":[
{
"name":"a",
"value":"Subfield a"
},
{
"name":"b",
"value":"Subfield b"
}
]
}
]
}
Run Code Online (Sandbox Code Playgroud)
dynamicFields
是一个数组,subfields
也是一个数组,当我点击这样的选择时遇到性能问题:
select *
from my_table a
cross join lateral jsonb_array_elements(jsonb_column -> 'dynamicFields') df
cross join lateral jsonb_array_elements(df -> 'subfields') sf
where df ->> 'name' = '200' and sf ->> 'name' = 'a'
Run Code Online (Sandbox Code Playgroud)
性能问题主要存在于subfield
. 我已经添加了这样的索引:
CREATE INDEX idx_my_index ON my_table USING gin ((marc->'dynamicFields') jsonb_path_ops);
Run Code Online (Sandbox Code Playgroud)
如何为subfields
内部添加索引dynamicFields
?
上面的查询只是一个示例,我在与数据库中其他表的联接中经常使用它。而且我也认识 …
postgresql ×9
jsonb ×8
sql ×8
indexing ×4
json ×4
arrays ×2
nested ×1
node.js ×1
sequelize.js ×1
typeorm ×1