[英]Rails: Search array json fields in postgresql db
认真地努力想出一个合理的范围。
我想使用 postgresql 获取在 json 数组列中具有特定“类型”字段的模型列表。
有人能指出我正确的方向吗,而且,我认为这是一个类级别的方法而不是一个范围,我只需要一个所有 Model.objects 的列表。
主要模型是Submission,它有一个:fmp_session——FmpSession有一个字段:project_data,这是一个postgresql :json类型的字段,包含一个json数组。
所以我想要的是所有提交的活动记录数组,如果 fmp_session.project_data 'type' json 键等于 'CREW'。
我宁愿坚持使用 activerecord 或 sql(或混合搭配),而不要理会 AREL。
我在想这样的事情:
Submission.joins(:fmp_session).where(
'EXISTS(
SELECT 1 from json_array_elements(
"project_data"
) project_data WHERE (
project_data#>> "{type}"
) = "CREW"
)'
)
从理论上讲,这将搜索 project_data 数组,并使用 #>> 搜索它,因此数组中有多少个元素并不重要——但我已经尝试了接近 40 次查询,但卡住了。 帮助我找到将一个表连接到另一个表并搜索特定字符串的 json 数组字段的正确查询。
更新
为了显示数据库部分,这里是该表的表描述(来自 psql)和 schema.db 段。 另外你应该知道
Column | Type |Modifiers
---------------+-----------+-----------------------------------------------------------
id | integer | not null default nextval('fmp_sessions_id_seq'::regclass)
project_data | json | default '[]'::json
和模式
create_table "fmp_sessions", force: :cascade do |t|
t.json "project_data", default: []
t.json "project_member_data", default: []
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
可能是您引用的问题:
Submission.joins(:fmp_session).where(
"EXISTS(
SELECT 1 from json_array_elements(
project_data
) project_data WHERE (
project_data#>> '{type}'
) = 'CREW'
)"
)
UPD:回复评论
查询很有用:
SELECT project_data#>> '{name}'
from json_array_elements(
'[
{
"id": "1",
"name": "First",
"type": "CREW"
},
{
"id": "2",
"name": "Second",
"type": "NOCREW"
},
{
"id": "3",
"name": "Third",
"type": "CREW"
}
]'
) project_data
WHERE project_data#>>'{type}' = 'CREW'
;
?column?
----------
First
Third
(2 rows)
SELECT EXISTS (SELECT 1
from json_array_elements(
'[
{
"id": "1",
"name": "First",
"type": "CREW"
},
{
"id": "2",
"name": "Second",
"type": "NOCREW"
},
{
"id": "3",
"name": "Third",
"type": "CREW"
}
]'
) project_data
WHERE project_data#>>'{type}' = 'CREW'
)
exists
--------
t
(1 row)
更新 2:PG12 功能。
PG12 添加了一些优秀的特性,允许在 json 中使用数组:
SELECT project_data @? '$[*] ? (@.type == "CREW")' AS res
FROM (SELECT '[
{"id": "1","name": "First","type": "CREW"},
{"id": "2","name": "Second","type": "NOCREW"},
{"id": "3","name": "Third","type": "CREW"}
]'::jsonb AS project_data) AS j;
res
----------
t
(1 row)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.