Elixir ecto:检查postgresql map列是否有密钥

时间:2016-06-19 03:27:32

标签: postgresql elixir ecto

使用json / jsonb数据类型ecto suggets [{3}}。

在我的情况下,我将使用PostgreSQL ?运算符来查看地图是否有这样的密钥,但是它会变成类似:

where(events, [e], e.type == 1 and not fragment("???", e.qualifiers, "?", "2"))

但当然fragment将PostgreSQL ?作为占位符读取。如何检查地图是否有这样的密钥?

1 个答案:

答案 0 :(得分:3)

您需要转义中间?并将总共三个参数传递给fragment

fragment("? \\? ?", e.qualifiers, "2")

演示:

iex(1)> MyApp.Repo.insert! %MyApp.Food{name: "Foo", meta: %{price: 1}}
iex(2)> MyApp.Repo.insert! %MyApp.Food{name: "Foo", meta: %{}}
iex(3)> MyApp.Repo.all from(f in MyApp.Food, where: fragment("? \\? ?", f.meta, "price"))
[debug] SELECT f0."id", f0."name", f0."meta", f0."inserted_at", f0."updated_at" FROM "foods" AS f0 WHERE (f0."meta" ? 'price') [] OK query=8.0ms
[%MyApp.Food{__meta__: #Ecto.Schema.Metadata<:loaded>, id: 1,
  inserted_at: #Ecto.DateTime<2016-06-19T03:51:40Z>, meta: %{"price" => 1},
  name: "Foo", updated_at: #Ecto.DateTime<2016-06-19T03:51:40Z>}]
iex(4)> MyApp.Repo.all from(f in MyApp.Food, where: fragment("? \\? ?", f.meta, "a"))
[debug] SELECT f0."id", f0."name", f0."meta", f0."inserted_at", f0."updated_at" FROM "foods" AS f0 WHERE (f0."meta" ? 'a') [] OK query=0.8ms
[]

我不确定这是否记录在任何地方,但我从this测试中找到了该方法。