在 Postgres 9.4+ 中索引 JSONB 嵌入式 Ecto2 模型
Posted
技术标签:
【中文标题】在 Postgres 9.4+ 中索引 JSONB 嵌入式 Ecto2 模型【英文标题】:Indexing of JSONB embedded Ecto2 models in Postgres 9.4+ 【发布时间】:2016-08-21 20:18:37 【问题描述】:我不清楚如何使用 Ecto2/Postgres 9.4+ 索引存储为 JSONB 的嵌入式结构
我有一个包含两个使用 embeds_one 和 embeds_many 的嵌入式结构的架构。它们是 ecto :map 字段,在 Postgres 中表示为 JSONB。我想知道如何确定它们被索引(使用 Gin?)以进行快速查询?我不确定这是否会自动发生,是否需要为迁移添加索引,或者是否需要使用 psql 等手动执行。
只是在寻找有关其工作原理的说明。 谢谢!
defmodule App.Repo.Migrations.CreateClient
def change do
create table(:clients) do
add :name, :string
add :settings, :map
add :roles, :array, :map, default: []
timestamps()
end
// This works for normal schema/model fields
create index(:clients, [:name], unique: true, using: :gin)
// BUT CAN I INDEX MY EMBEDS HERE?
// GUESS:
create index(:clients, [:settings], using: :gin)
end
end
defmodule App.Client do
schema "client" do
field :name, :string
embeds_one :settings, Settings // single fixed schema "Settings" model
embeds_many :roles, Role // array of "Role" models
end
end
defmodule Settings do
use Ecto.Model
embedded_schema do // ALSO
field :name, :string // are types relevant?
field :x_count, :integer // stored as strings (INDEXED?)
field :is_active, :boolean // deserialized via cast?
end
end
defmodule Role do
use Ecto.Model
embedded_schema do
field :token
field :display_english
field :display_spanish
end
end
【问题讨论】:
【参考方案1】:我想你只需要添加这个:
create index(:clients, [:name], unique: true, using: :gin)
到您的迁移文件。
或者如果索引 sql 语句会很复杂,你可以用execute
来做,所以它会是这样的:
execute("CREATE INDEX clients_name_index ON clients USING GIN (name)")
我还没有测试过,但我相信它应该可以工作。
【讨论】:
这绝对适合客户端模型中的***字段,但我问的是关于索引 JSONB :map 字段 好吧,去here 并查看jsonb Indexing
部分,jsonb 列的语法与通常的列基本相同,所以我的第一个示例应该可以工作,除非您添加一些特定选项索引,您将使用execute
here is an example with elixir/ecto。 and another for querying the maps以上是关于在 Postgres 9.4+ 中索引 JSONB 嵌入式 Ecto2 模型的主要内容,如果未能解决你的问题,请参考以下文章
使用 postgres 9.4 将 JSON 元素附加到数组
如何使用 Postgres jsonb '? Laravel 中具有索引支持的运算符?