Luc*_*rna 6 arrays postgresql json ruby-on-rails jsonb
我试图在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') ->> 'serie' from users;
Run Code Online (Sandbox Code Playgroud)
我想我没有在列中正确传递数据.我提供的哈希是:
pry(#<Overrides::RegistrationsController>)> @response['data']['user']
=> {"last_name"=>"Doe1",
"first_name"=>"John1",
"email"=>"c0f45@example.com",
"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)
保存资源之前,如下所示:
pry(#<Overrides::RegistrationsController>)> @resource
=> #<User id: nil, provider: "email", uid: "", first_name: "John1", last_name: "Doe1", email: "c0f45@example.com", role: "Student", created_at: nil, updated_at: nil, 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)
Erw*_*ter 12
假设:
{"serie": 5}.可能还有其他的." 简短的回答:使用jsonb而不是,json这只是工作:
User.where("groups @> ?", '[{"serie": 5}]')
Run Code Online (Sandbox Code Playgroud)
注意方括号使右侧操作数成为JSON 数组.
这里突出的误区:数据类型json不一样 jsonb.
您没有声明实际的表定义,但您后来发表了评论,json并且问题中有一个提示:
Run Code Online (Sandbox Code Playgroud)select json_array_elements(groups -> 'data') ->> 'serie' from users;
json_array_elements()只适用于json,必须jsonb_array_elements()适用jsonb.
但是你试图使用jsonb运算符 @>,这是不可能的json:
Run Code Online (Sandbox Code Playgroud)groups -> 'data' @> '?'
所述操作者->将返回相同类型的左手输入.但@>只是定义jsonb,而不是json.
然后,您尝试使用运营商@>对于text为左侧操作数.也不可能:
Run Code Online (Sandbox Code Playgroud)groups ->> 'data' @> ?
@>各种类型(包括Postgres数组)都有运算符的变体,但不适用于text和不适用json.
所以,简短的回答:使用jsonb而不是json.这也允许使用非常有效的索引:
json对于数据类型,json您可以使用:
SELECT *
FROM users u
WHERE EXISTS (
SELECT 1
FROM json_array_elements(u.groups) elem
WHERE elem ->> 'serie' = '5'
);
Run Code Online (Sandbox Code Playgroud)
jsonb:
SELECT *
FROM (
VALUES (1, jsonb '[{"serie":5, "year":3, "specialization":"Matematica", "management_id":1, "group_number":2}
, {"serie":5, "year":3, "specialization":"Matematica", "management_id":1, "group_number":2}]')
, (2, '[{"serie":7, "year":3, "specialization":"Matematica", "management_id":1, "group_number":2}
, {"serie":8, "year":3, "specialization":"Matematica", "management_id":1, "group_number":2}]')
, (3, '[{"serie":9, "year":3, "specialization":"Matematica", "management_id":1, "group_number":2}
, {"serie":5, "year":3, "specialization":"Matematica", "management_id":1, "group_number":2}]')
) users(id, groups)
WHERE groups @> '[{"serie": 5}]';
Run Code Online (Sandbox Code Playgroud)
json:
SELECT *
FROM (
VALUES (1, json '[{"serie":5, "year":3, "specialization":"Matematica", "management_id":1, "group_number":2}
, {"serie":5, "year":3, "specialization":"Matematica", "management_id":1, "group_number":2}]')
, (2, '[{"serie":7, "year":3, "specialization":"Matematica", "management_id":1, "group_number":2}
, {"serie":8, "year":3, "specialization":"Matematica", "management_id":1, "group_number":2}]')
, (3, '[{"serie":9, "year":3, "specialization":"Matematica", "management_id":1, "group_number":2}
, {"serie":5, "year":3, "specialization":"Matematica", "management_id":1, "group_number":2}]')
) users(id, groups)
WHERE EXISTS (
SELECT 1
FROM json_array_elements(users.groups) elem
WHERE elem ->> 'serie' = '5'
);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4121 次 |
| 最近记录: |