[英]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.