能否在使用NPGSQL的CodeFirst EntityFramework中指定JSONB GIN索引?

4

我在EFCore项目中的EF代码优先对象上有一些JSONB列。我想将存储为JSONB属性/列的强类型对象中的某些属性设置为GIN索引。
这可能吗?(目前正在使用postgres:latest镜像)

谢谢。

4个回答

8

由于 .ForNpgsqlHasMethod("gin") 已过时,因此在 EF Core 3.1 中你可以使用以下方式:

metaBuilder
    .HasIndex(x => x.DocumentNumber)
    .HasMethod("gin")
    .HasOperators("gin_trgm_ops");

你的迁移将如下所示:

migrationBuilder.CreateIndex(
    name: "IX_DocumentContentMeta_DocumentNumber",
    table: "DocumentContentMeta",
    column: "DocumentNumber")
    .Annotation("Npgsql:IndexMethod", "gin")
    .Annotation("Npgsql:IndexOperators", new[] { "gin_trgm_ops" });

你需要在PostgreSQL数据库中做其他的事情来启用支持吗?我遇到了异常:'42704:操作符类“gin_trgm_ops”不存在于访问方法“gin”中。这需要特定的PostgreSQL版本才能工作吗? - nikib3ro
@nikib3ro 是的,请尝试在您的数据库上执行 CREATE EXTENSION pg_trgm; - Sam Sch

4

嗯,实际上你可以这样做

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Artist>()
       .HasIndex(a => new { a.Album })
       .ForNpgsqlHasMethod("gin");

    base.OnModelCreating(modelBuilder);
}

当您运行ef add migration时,生成的SQL查询将如下所示:

CREATE INDEX ix_artist_album ON artist USING gin ("album");

Npgsql文档中的说明:http://www.npgsql.org/efcore/modeling/indexes.html

由于某种原因,我认为在原始帖子中看到的是Entity Framework 6,而不是Entity Framework Core... - Shay Rojansky

3
第一步:创建索引
modelBuilder.Entity<MyAwesomeModel>()
    .HasIndex(f => f.stringToTriGram)
    .HasMethod("gin")
    .HasOperators("gin_trgm_ops");

第二步:启用TrigramExtension
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);
    modelBuilder.HasPostgresExtension("pg_trgm");
}

1

通过Npgsql EF6提供程序没有特定的方法设置GIN索引。但是,您可以在迁移中使用原始SQL手动设置它。

但是,正如@hellokitty5685在另一个答案中所写的那样,这在EF Core中是可能的。


谢谢,我就是担心这个。既然如此,我立刻考虑创建一个自定义属性,其中包含应用于属性的GIN索引信息。你知道是否有一种模式可以从服务项目中管理手动架构更改吗? - Bob
我不确定你的意思是什么 - 你需要自己创建迁移并手动编写添加索引的SQL语句。顺便说一下,注意EF Core提供程序确实支持指定GIN索引:http://www.npgsql.org/efcore/modeling/indexes.html - Shay Rojansky
一直在看你提到的页面(再次)。我在想是否可以在数据库中编写一个自定义运算符,然后使用ForNpgsqlHasOperators来覆盖EF中任意数量的JSONB字段,并具有正常的索引。在这个例子中,使用GiST索引方法编写了一个Create Operator...我会研究一下可能使用GIN变体实现这一点:https://www.postgresql.org/docs/9.3/sql-createopclass.html。再次感谢。 - Bob
我认为如果没有使用“CREATE INDEX... USING gin”你将无法创建GIN索引......但是我在这方面不是很专家。 - Shay Rojansky

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接