23

我正在使用 Rails 4.2 和 Postgres 9.4 来尝试新的 JSONB 数据类型。我的数据库中的 JSONB 列之一包含一个数组,我希望能够查询该数组包含某个值的记录。我想出了如何使用新的 JSONB“问号”(“包含”)运算符来做到这一点,如此处所述: http ://www.postgresql.org/docs/9.4/static/functions-json.html

所以在原始 SQL 中,我可以让它像这个例子一样工作:

SELECT * FROM people WHERE roles ? '32486d83-4a38-42ba-afdb-f77ca40ea1fc';

但是我看不到通过 ActiveRecord 在 Rails 中执行此查询的任何方法。我尝试使用“where”方法进行原始查询,如下所示:

Person.where("roles ? ?", "32486d83-4a38-42ba-afdb-f77ca40ea1fc")

但由于问号是用于替换参数的特殊字符,我得到这个错误:

ActiveRecord::PreparedStatementInvalid:绑定变量的数量错误(1 对 2):角色??

我想我需要一种方法来逃避“?” 字符,因为我希望它从字面上通过。我试过了 \?和 ??没有运气。任何帮助表示赞赏!

4

2 回答 2

42

你应该这样称呼它:

Person.where("roles ? :name", name: "32486d83-4a38-42ba-afdb-f77ca40ea1fc")
于 2015-06-04T17:23:48.277 回答
14

一种解决方法。运行此查询以找出您的运算符映射到的函数:

SELECT 
  oprname, 
  oprcode || '(' || format_type(oprleft,  NULL::integer) || ', ' 
                 || format_type(oprright, NULL::integer) || ')' AS function
FROM pg_operator 
WHERE oprname = '?';

它产生

oprname  function
?        jsonb_exists(jsonb, text)
?        exist(hstore, text)

现在在查询中使用该函数而不是运算符:

Person.where("jsonb_exists(roles, ?)", "32486d83-4a38-42ba-afdb-f77ca40ea1fc")
于 2016-07-14T12:56:48.890 回答