我想使用postgres IN运算符(使用Ecto库)查询jsonb字段
此代码使用simple =运算符:
from a in query, where: fragment("?->>'format' = ?", a.properties, "foo")
但我无法做出任何这些尝试:
from a in query, where: fragment("?->>'format' IN ?", a.properties, ["foo", "bar"]) from a in query, where: fragment("?->>'format' IN (?)", a.properties, ["foo", "bar"]) from a in query, where: fragment("?->>'format' IN ?", a.properties, "('foo', 'bar')"])
任何的想法?
除了Patrick的出色响应之外,请记住,您也只能将部分查询放入片段中.例如,您可以将其重写为:
from a in query, where: fragment("?->>'format', a.properties) in ["foo", "bar"]
如果您将片段放在宏中,您甚至可以获得可读的语法:
defmacro jsonb_get(left, right) do quote do fragment("?->>?", unquote(left), unquote(right)) end end
现在:
from a in query, where: jsonb_get(a.properties, "format") in ["foo", "bar"]
这与JSONB无关.Ecto会将您的类型列表转换为PostgresARRAY
,但不适用于IN
运营商:
psql> SELECT 1 IN(ARRAY[1, 2, 3]); ERROR: operator does not exist: integer = integer[]
但是,您可以使用= ANY()
以检查值是否包含在ARRAY
:
psql> SELECT 1 = ANY(ARRAY[1, 2, 3]); ?column? ---------- t (1 row)
您应该能够使用以下片段来实现与Ecto相同的功能:
fragment("?->>'format' = ANY(?)", u.properties, ["foo", "bar"])