关于postgresql:Postgres 9.4+中JSONB嵌入式Ecto2模型的索引

Indexing of JSONB embedded Ecto2 models in Postgres 9.4+

我不清楚如何使用Ecto2 / Postgres 9.4+索引存储为JSONB的嵌入式结构

我有一个使用embeds_one和embeds_many的两个嵌入式结构的模式。 它们是ecto:Postgres中表示的地图字段为JSONB。 我想知道如何确保它们被编入索引(使用Gin?)以进行快速查询? 我不确定这是否会自动发生,如果我需要为我的迁移添加索引或者我需要使用psql等手动执行此操作。

只是想澄清它是如何工作的。
谢谢!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
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来做,所以它会是这样的:

1
EXECUTE("CREATE INDEX clients_name_index ON clients USING GIN (name)")

我没有测试过,但我相信它应该可行。