簡體   English   中英

Rails:在 postgresql db 中搜索數組 json 字段

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM