繁体   English   中英

ts_vector_update_trigger与postgresql / npgsql + EFCore中的JSONB列

[英]ts_vector_update_trigger with JSONB column in postgresql / npgsql + EFCore

在EFCore + npgsql中,使用postgresql 10,我想创建一个tsvector列以允许对模型中某些字段进行全文搜索:

public class MyModel
{
  public string Title { get; set; }

  public string Description { get; set; }

  [Column(TypeName = "jsonb")]
  public string JSON { get; set; }
}

我希望全文搜索包括JSONB列中的值,因此根据npgsql文档,我像这样更新模型:

public class MyModel
{
  public string Title { get; set; }

  public string Description { get; set; }

  [Column(TypeName = "jsonb")]
  public string JSON { get; set; }

  public NpgsqlTsVector SearchVector { get; set; }
}

在数据库上下文中的OnModelCreating中添加以下索引:

  modelBuilder.Entity<MyModel>(m =>
  {
    // create some other indexes
    m.HasIndex(e => new { e.SearchVector }).ForNpgsqlHasMethod("GIN");
  });

然后创建迁移并根据文档进行编辑以获取以下方法:

protected override void Up(MigrationBuilder migrationBuilder)
{
  migrationBuilder.AddColumn<NpgsqlTsVector>(
    name: "SearchVector",
    table: "MyModels",
    nullable: true);

  migrationBuilder.CreateIndex(
    name: "IX_MyModels_SearchVector",
    table: "MyModels",
    column: "SearchVector")
    .Annotation("Npgsql:IndexMethod", "GIN");

  migrationBuilder.Sql(
    @"CREATE TRIGGER my_model_search_vector_update BEFORE INSERT OR UPDATE
    ON ""MyModels"" FOR EACH ROW EXECUTE PROCEDURE
    tsvector_update_trigger(""SearchVector"", 'pg_catalog.english', ""Title"", ""Description"", ""JSON"");");

  // I am updating an existing table, so:
  migrationBuilder.Sql("UPDATE \"MyModels\" SET \"Title\" = \"Title\";");
}

protected override void Down(MigrationBuilder migrationBuilder)
{
  migrationBuilder.DropIndex(
    name: "IX_MyModels_SearchVector",
    table: "MyModels");

  migrationBuilder.DropColumn(
    name: "SearchVector",
    table: "MyModels");

  migrationBuilder.Sql("DROP TRIGGER my_model_search_vector_update");
}

但是毕竟,在应用更新数据库时,我看到:

Failed executing DbCommand (50ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
UPDATE "MyModels" SET "Title" = "Title";
Npgsql.PostgresException: column "JSON" is not of a character type

我认为这是因为JSONB列是二进制数据。 是否有可能实现我的期望? 我对Postgresql,npgsql和EFCore比较陌生。

我很确定您不能通过PostgreSQL jsonb进行全文搜索,因为正如您所写的那样,它不是文本类型。 使用json会有一个小的变化-因为这是文本存储-但这种类型更接近简单的text ,并且没有提供二进制jsonb许多优点。

但是,取决于您要执行的操作, jsonb具有很多搜索功能(SQL / JSON JSONPATH也包含在PostgreSQL 12中)。 该功能当前尚未在EF Core中进行映射,但这并不能真正阻止您通过原始SQL使用它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM