Rails:在postgresql db中搜索数组json字段

时间:2017-03-07 00:55:45

标签: ruby-on-rails json postgresql

认真努力想出一个合理的范围。

我想获得一个Model列表,它使用postgresql在json数组列中有一个特定的“type”字段。

有人能指出我正确的方向吗,我也很好,这是一个类级方法而不是范围,我只需要一个所有Model.objects的列表。

主要模型是Submission,其中has_one:fmp_session - FmpSession有一个字段:project_data,它是一个postgresql:json类型字段,包含一个json数组。

所以我想要的是所有提交的活动记录数组,如果fmp_session.project_data'类型'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

1 个答案:

答案 0 :(得分:0)

可能是引用中的问题:

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)