Rails通过JSON属性搜索

时间:2018-06-05 20:43:43

标签: sql ruby-on-rails json postgresql

我有一个Foo模型。它有关键字。

create_table "foos", force: :cascade do |t|
  t.json "keywords"
end

关键字存储为数组:["quick", "brown", "fox"]

我想知道如何使用其中一个关键字"fox"来选择foos。

我正在看这个video,它说使用类似WHERE details -> 'tags' ? 'techie'

的内容

但这仅适用,因为他们示例中的details是哈希

{
  "contacts": [...],
  "tags": [...]
}

我不是在挖掘哈希,我只想搜索一个数组。我试过这个:

Foo.where("keywords -> 'fox'")

但它提出了

ActiveRecord::StatementInvalid: PG::DatatypeMismatch: ERROR:  argument of WHERE must be type boolean, not type json
LINE 1: SELECT  "foos".* FROM "foos" WHERE (keywords -> 'fox') LIM...
                                              ^
: SELECT  "foos".* FROM "foos" WHERE (keywords -> 'fox') LIMIT $1

tutorial建议使用?| array[:keys],如下所示:

Foo.where('keywords ?| array[:keys]', keys: ['brown', 'fox'])

但我得到同样的错误

ActiveRecord::StatementInvalid: PG::UndefinedFunction: ERROR:  operator does not exist: json ?| text[]
LINE 1: SELECT  "foos".* FROM "foos" WHERE (keywords ?| array['fox...
                                                       ^
HINT:  No operator matches the given name and argument type(s). You might need to add explicit type casts.
: SELECT  "foos".* FROM "foos" WHERE (keywords ?| array['fox','quick']) LIMIT $1

想点什么?

1 个答案:

答案 0 :(得分:1)

您必须使用JSONB数据类型而不是JSONHere 是一个很好的话题。

比较

> select '["a", "fox", "c"]'::jsonb ?| array['fox','quick'] as exists;

 exists
--------
 t
(1 row)

> select '["a", "fox", "c"]'::json ?| array['fox','quick'] as exists;

ERROR:  operator does not exist: json ?| text[]
LINE 1: select '["a", "fox", "c"]'::json ?| array['fox','quick'] as ...

P.S。然后,您可以选择索引keywords列。