我有一个看起来像这样的表:
CREATE TABLE tracks (id SERIAL, artists JSON);
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)
还有其他几个与此问题无关的列.将它们存储为JSON是有原因的.
我要做的是查找具有特定艺术家姓名(完全匹配)的曲目.
我正在使用此查询:
SELECT * FROM tracks
WHERE 'ARTIST NAME' IN
(SELECT value->>'name' FROM json_array_elements(artists))
Run Code Online (Sandbox Code Playgroud)
例如
SELECT * FROM tracks
WHERE 'The Dirty Heads' IN
(SELECT value->>'name' FROM json_array_elements(artists))
Run Code Online (Sandbox Code Playgroud)
但是,这会进行全表扫描,并且速度不是很快.我尝试使用函数创建GIN索引names_as_array(artists)并使用'ARTIST NAME' = ANY names_as_array(artists),但是不使用索引并且查询实际上明显更慢.
我有一个JSONB字段,有时有嵌套键.例:
"a simple text"
如果我这样做,
"a simple text"
我会得到这个记录.
如何搜索嵌套密钥的存在?("a simple text")
我试图在Postgres数据库中查询某个值.我有一个groups在users表中命名的字段,可以用以下任何一种方式表示:
1.
groups: {"data"=>[{"serie"=>5, "year"=>3, "specialization"=>"Matematica", "management_id"=>1, "group_number"=>2}, {"serie"=>5, "year"=>3, "specialization"=>"Matematica", "management_id"=>1, "group_number"=>2}]}
Run Code Online (Sandbox Code Playgroud)
2.
groups: [{"serie"=>5, "year"=>3, "specialization"=>"Matematica", "management_id"=>1, "group_number"=>2}, {"serie"=>5, "year"=>3, "specialization"=>"Matematica", "management_id"=>1, "group_number"=>2}]
Run Code Online (Sandbox Code Playgroud)
我对这两种表述都很好.但是,我似乎无法找到如何让所有在系列5中的用户让我们说.我尝试了多个查询:
@users = User.where("groups ->> 'data' @> ?", {serie: 5})
@users = User.where("groups -> 'data' @> '?'", {serie: 5})
@users = User.where("groups ->> 'data' ->> 'serie' = ?", 5)
Run Code Online (Sandbox Code Playgroud)
还有许多其他尝试,有些比其他尝试更愚蠢(见上文).我该怎么办?
我已经能够确定:
select groups -> 'data' ->> 'serie' from users;
ERROR: cannot extract field from a non-object.
Run Code Online (Sandbox Code Playgroud)
但是以下查询有效:
select json_array_elements(groups -> 'data') …Run Code Online (Sandbox Code Playgroud)