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

Tay*_*sky 3 postgresql ruby-on-rails rails-activerecord postgresql-9.4

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

我正在使用Postgres/Postgresql并且有一个jsonb类型,我想做类似的事情.伪代码:.where("col @> ?", {attr: [val1, val2, val3]}.to_json),但是这没有返回-公元前它试图找到整个阵列的值[val1, val2, val3 ]不是每个单独的值:val1,val2,val3

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

我能做到.where("attr @> {.. val1 ...} OR attr @> {... val2 ..} ..."),但似乎会有更好的方法.

我从https://www.postgresql.org/docs/9.4/static/functions-json.html尝试了各种各样的东西,但似乎有一个避开我的解决方案.

mu *_*ort 10

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

9.23.3.ANY/SOME(数组)

expression operator ANY (array expression)
expression operator SOME (array expression)
Run Code Online (Sandbox Code Playgroud)

所以像这样:

where c = 1 or c = 2 or c = 3
Run Code Online (Sandbox Code Playgroud)

可以写成:

where c = any(array[1,2,3])
Run Code Online (Sandbox Code Playgroud)

运营商不必是=或课程,也可以是>,like或甚@>.此外,如果占位符的值是一个数组,那么ActiveRecord会将该数组扩展为SQL中的逗号分隔列表,例如:

where('c = any(array[?])', [1,2,3])
Run Code Online (Sandbox Code Playgroud)

会变成:

where c = any(array[1,2,3])
Run Code Online (Sandbox Code Playgroud)

到数据库看到它的时候.

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

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

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