首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Ecto + Elixir:如何查询hashmap字段?

Ecto + Elixir:如何查询hashmap字段?
EN

Stack Overflow用户
提问于 2016-12-06 23:16:29
回答 1查看 1.1K关注 0票数 2

我有个模特:

代码语言:javascript
复制
defmodule VideoChat.User do
  use VideoChat.Web, :model

  schema "users" do
    field :device_identifier, :string
    field :matches, :map

    timestamps()
  end

  ...
end

我如何查找所有在matches哈希中使用“酷”键的用户?

User |> where([u], u.matches["cool"] != nil) |> limit(1) |> VideoChat.Repo.one

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-12-07 10:24:52

Ecto将:map字段存储为PostgreSQL中的JSONB字段。Ecto不提供任何函数来对这些字段进行映射特定的操作,但可以使用fragment和自定义SQL来完成。

SQL查询foo.bar ? 'baz'将检查foo的列bar是否包含键"baz"中的值。这可以用这样的fragment来表示:

代码语言:javascript
复制
fragment("? \\? ?", foo.bar, "baz")

因此,您的代码应该修改为:

代码语言:javascript
复制
User |> where([u], fragment("? \\? ?", u.matches, "cool")) |> limit(1) |> VideoChat.Repo.one

在一种全新的Map模型中,:map类型的键map

代码语言:javascript
复制
iex(1)> Repo.insert! %MyApp.Map{map: %{}}
iex(2)> Repo.insert! %MyApp.Map{map: %{foo: 1}}
iex(3)> Repo.insert! %MyApp.Map{map: %{foo: 2}}
iex(4)> Repo.insert! %MyApp.Map{map: %{bar: 1}}
iex(5)> Repo.all MyApp.Map |> where([m], fragment("? \\? ?", m.map, "foo"))
[debug] QUERY OK source="maps" db=1.8ms decode=5.3ms
SELECT m0."id", m0."map", m0."inserted_at", m0."updated_at" FROM "maps" AS m0 WHERE (m0."map" ? 'foo') []
[%MyApp.Map{__meta__: #Ecto.Schema.Metadata<:loaded, "maps">, id: 2,
  inserted_at: #Ecto.DateTime<2016-12-07 10:19:53>, map: %{"foo" => 1},
  updated_at: #Ecto.DateTime<2016-12-07 10:19:53>},
 %MyApp.Map{__meta__: #Ecto.Schema.Metadata<:loaded, "maps">, id: 3,
  inserted_at: #Ecto.DateTime<2016-12-07 10:19:55>, map: %{"foo" => 2},
  updated_at: #Ecto.DateTime<2016-12-07 10:19:55>}]
iex(6)> Repo.all MyApp.Map |> where([m], fragment("? \\? ?", m.map, "bar"))
[debug] QUERY OK source="maps" db=2.9ms queue=0.2ms
SELECT m0."id", m0."map", m0."inserted_at", m0."updated_at" FROM "maps" AS m0 WHERE (m0."map" ? 'bar') []
[%MyApp.Map{__meta__: #Ecto.Schema.Metadata<:loaded, "maps">, id: 4,
  inserted_at: #Ecto.DateTime<2016-12-07 10:19:59>, map: %{"bar" => 1},
  updated_at: #Ecto.DateTime<2016-12-07 10:19:59>}]
iex(7)> Repo.all MyApp.Map |> where([m], fragment("? \\? ?", m.map, "baz"))
[debug] QUERY OK source="maps" db=2.2ms queue=0.1ms
SELECT m0."id", m0."map", m0."inserted_at", m0."updated_at" FROM "maps" AS m0 WHERE (m0."map" ? 'baz') []
[]
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41006696

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档