0

我有一個具有JSONB列contentPage模型的Rails 5項目。因此,結構看起來像這樣(降低到最低限度的問題):在Rails中的JSONB查詢包含哈希數組的鍵

#<Page id: 46, content: {..., "media" => [{ "resource_id" => 143, "other_key" => "value", ...}, ...], ...}> 

我將如何編寫一個查詢發現,有一些所需數量的resource_idcontent JSONB的media鍵下的所有網頁柱?這是我做了一個不起作用的嘗試(我認爲是因爲在陣列的每個項目中還有其他鍵/值對): Page.where("content -> 'media' @> ?", {resource_id: '143'}.to_json)

編輯:這個工作,但只會檢查第一個哈希媒體數組:Page.where("content -> 'media' -> 0 ->> 'resource_id' = ?", '143')

回答

2

使用SQL,這應該給你具有資源ID 143的所有頁面:

select * from pages p where '{"resource_id": 143}' <@ ANY (ARRAY(select jsonb_array_elements (content -> 'media') from pages where id=p.id)); 

PostgreSQL有一個名爲ANY(postgres docs)功能,採用的形式expression operator ANY (array)。使用給定的運算符評估左側表達式並與數組的每個元素進行比較。

由於ANY的右側參數必須是數組(不是json數組),我們使用jsonb_array_elements方法將content-> media json數組轉換爲一組行,然後將其轉換爲數組通過使用ARRAY()。

<@運算符檢查右側的表達式是否包含左側的表達式。例如:'{"a": 1}'::jsonb <@ '{"b": 2, "a": 1}'::jsonb將返回true。

+0

謝謝,這是非常有幫助的。使用Rails而不是直接SQL,我編寫了這個查詢,它給了我所需要的: 'Page.where(「'{\」resource_id \「:?}'<@ ANY(ARRAY(select jsonb_array_elements(content - >) 'media')))「,143)' – Lee