繁体   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