Postgresql jsonb(Rails) - 通过数组在单个json属性中查询多个值

时间:2016-08-18 16:05:26

标签: ruby-on-rails postgresql rails-activerecord postgresql-9.4

在Rails中,我可以.where(:attr => [val1, val2, val3]),我会找回与val1-3中的任何一行匹配的所有行。

我正在使用Postgres / Postgresql并且有一个jsonb类型,我想做类似的事情。 PsuedoCode:.where("col @> ?", {attr: [val1, val2, val3]}.to_json),但这不返回任何内容 - bc它试图找到整个数组[val1, val2, val3 ]的值而不是每个单独的值:val1val2,{{ 1}?

有没有办法在jsonb查询中传递相对于单个属性的多个值?

我可以做val3,但似乎会有更好的方式。

我从https://www.postgresql.org/docs/9.4/static/functions-json.html尝试了各种各样的事情,但似乎有一种解决方法可以避开我。

1 个答案:

答案 0 :(得分:9)

您通常可以使用ANY来概括OR表达式:

  

<强> 9.23.3。 ANY / SOME(数组)

expression operator ANY (array expression)
expression operator SOME (array expression)

这样的事情:

where c = 1 or c = 2 or c = 3

可以写成:

where c = any(array[1,2,3])

运算符不一定是=或课程,可以是>like,甚至是@>。此外,如果占位符的值是一个数组,那么ActiveRecord会将该数组扩展为SQL中的逗号分隔列表,如下所示:

where('c = any(array[?])', [1,2,3])

将成为:

where c = any(array[1,2,3])

到数据库看到它时。

将上述内容与您的JSON结合使用可以得到以下内容:

where('attr @> any(array[?]::jsonb[])', [val1, val2, val3].map(&:to_json))

::jsonb[]是一个类型转换,以确保PostgreSQL将数组视为jsonb的数组,而不是text的数组。