2016-06-19 5 views
1

json/jsonbデータタイプecto suggetsを使用する場合to use fragmentsElixir ecto:postgresqlのマップカラムにキーがあるかどうかを確認します。

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

もちろんfragment

としてPostgreSQLの ?を読み取ります

私の場合、私は、これはしかし、それは何かのようになり、マップは、キーを持っているかどうかを確認するためにPostgreSQLの?演算子を使用してきましたプレースホルダ。マップにそのようなキーがあるかどうかを確認するにはどうすればよいですか?

答えて

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 
[] 

私は、これはどこでも文書化されているかどうかわからないんだけど、I方法は、thisテストから見つかりました。

+0

ええ私もそれを使用することができるようにectoをアップグレードしなければならなかったことを発見しました。 – alex88

+0

これはElixirもエスケープ文字として\を使用しているため、Postgresが1 \を得られるようにエスケープする必要があります。 '〜S'を使うこともできます:'〜S |? \? ? == "?\\?" "'。 – Dogbert

関連する問題