Ecto.Query.API.json_extract_path
json_extract_path
, go back to Ecto.Query.API module for more information.
Returns value from the json_field
pointed to by path
.
from(post in Post, select: json_extract_path(post.meta, ["author", "name"]))
The query can be also rewritten as:
from(post in Post, select: post.meta["author"]["name"])
Path elements can be integers to access values in JSON arrays:
from(post in Post, select: post.meta["tags"][0]["name"])
Any element of the path can be dynamic:
field = "name"
from(post in Post, select: post.meta["author"][^field])
Warning
The underlying data in the JSON column is returned without any
additional decoding. This means "null" JSON values are not the
same as SQL's "null". For example, the Repo.all
operation below
returns an empty list because p.meta["author"]
returns JSON's
null and therefore is_nil
does not succeed:
Repo.insert!(%Post{meta: %{author: nil}})
Repo.all(from(post in Post, where: is_nil(p.meta["author"])))
Similarly, other types, such as datetimes, are returned as strings.
This means conditions like post.meta["published_at"] > from_now(-1, "day")
may return incorrect results or fail as the underlying database
tries to compare incompatible types. You can, however, use type/2
to force the types on the database level.