【问题标题】:Rails 4 Querying a hstore array?Rails 4查询hstore数组?
【发布时间】:2014-08-10 16:45:56
【问题描述】:

我在rails 4.1.4 上的postgres 9.3.2 数据库的reviews 表中有一个答案hstore 数组列

add_column :reviews, :answers, :hstore, array:true

具有这样的值:

=> [{"qid"=>"299", "val"=>"1", "field_type"=>"rating_field"}, {"qid"=>"300", "val"=>"2", "field_type"=>"rating_field"}]

我正在尝试从 qid == 299 获取所有值,所以输出应该是1,或者当有多个值时是一个数组

我试过了:Review.where("answers -> 'qid' = '299'")["val"]

一些想法?

谢谢,帕特里克

【问题讨论】:

    标签: ruby-on-rails arrays postgresql-9.3 hstore ruby-on-rails-4.1


    【解决方案1】:

    您可以为此编写一个范围。
    我正在专门为 hstore 数组在 Surus 之上创建一些额外的范围。:https://github.com/jackc/surus

    这个 gem 帮助了我,它已经为您提供了在常规 hstore 上工作的范围。

    专门用于 hstore 数组。 在 hstore 数组上做这种工作可能非常棘手,

    基本上我们想要取消嵌套数组,将其转换回 hstore,然后使用 hstore 操作数 @> 检查右手键 => 值对是否存在于左手子选择中。实现这一点的唯一方法是使用子查询。

    Review.where(" exists ( SELECT * FROM  ( SELECT  hstore(unnest(reviews.answers)))  x(item)      WHERE x.item  @> '"qid" => "299"')"); 
    

    这应该很好用。 查看我的 fork,https://github.com/milankubin/surus 它现在将为您提供两个范围:

    Model.hstore_array_has_any(column, value) # 将在数组中查找任何匹配值 Model.hstore_array_has_pairs(column, hash) # 你要找的答案:)

    => #<ActiveRecord::Relation []>
    2.1.2 :002 > Lead.hstore_array_has_pairs(:m3_data, {"name" => "3-zitsbank"})
    Lead Load (2.0ms)  SELECT "leads".* FROM "leads"  WHERE ( exists (  SELECT * FROM  (     SELECT hstore(unnest("m3_data")))  x(item)  WHERE x.item  @> '"name"=>"3-zitsbank"'))
    => #<ActiveRecord::Relation [#<Lead id: 35655,[.......]
    

    hstore 不支持索引是不正确的。您可以对单个键进行索引,甚至可以在嵌套在 hstore 数组中时进行索引。但这并不容易,并且需要您在添加索引时编写自己的索引规划器。

    看看这个答案,这可能会让你开始: PostgreSQL - query against GIN index of HSTORE value

    我还没有冒险进入这个世界,但肯定有可能。

    【讨论】:

      【解决方案2】:

      通过这个答案

      https://stackoverflow.com/a/10117278/1436131

      一个 posgresql 数组只是一个字符串,所以你不能索引它。相反,您可能希望查看 Posgresql 对 JSON 的本机支持,而不是他们建议的另一个连接表。

      http://www.postgresql.org/docs/9.3/static/functions-json.html

      以下答案让您很好地了解如何执行此操作。

      https://stackoverflow.com/a/22290601/1436131

      【讨论】:

      【解决方案3】:

      试试这个: Review.where("answers -&gt;&gt; 'qid' = '299'").first.answers['val']

      【讨论】:

        猜你喜欢
        • 2013-12-01
        • 2015-01-25
        • 1970-01-01
        • 2016-05-17
        • 2013-06-27
        • 2015-03-22
        • 2014-08-31
        • 2017-04-05
        • 2015-08-12
        相关资源
        最近更新 更多