简体   繁体   English

ts_vector_update_trigger与postgresql / npgsql + EFCore中的JSONB列

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

In EFCore + npgsql, using postgresql 10, I want to create a tsvector column to allow full text search of some fields in a model: 在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; }
}

I want the full text search to include values from the JSONB column, so as according to the npgsql docs I update my model like so: 我希望全文搜索包括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; }
}

add the following index in OnModelCreating in my DB context: 在数据库上下文中的OnModelCreating中添加以下索引:

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

Then create the migration and edit (in accordance with docs) to get the following methods: 然后创建迁移并根据文档进行编辑以获取以下方法:

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");
}

But after all this, when applying Update-Database, I see: 但是毕竟,在应用更新数据库时,我看到:

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

I assume this is because the JSONB column is binary data. 我认为这是因为JSONB列是二进制数据。 Is it possible to achieve what I'm looking for? 是否有可能实现我的期望? I'm relatively new to postgresql, npgsql and EFCore. 我对Postgresql,npgsql和EFCore比较陌生。

I'm pretty sure you can't do full-text search over PostgreSQL jsonb because, as you wrote, it's not a text type. 我很确定您不能通过PostgreSQL jsonb进行全文搜索,因为正如您所写的那样,它不是文本类型。 There's a small change that using json would work - as that's textual storage - but that type is much closer to simple text and doesn't offer many of the advantages of binary jsonb . 使用json会有一个小的变化-因为这是文本存储-但这种类型更接近简单的text ,并且没有提供二进制jsonb许多优点。

However, depending on exactly what you want to do, jsonb has quite a lot of search functionality (with SQL/JSON JSONPATH also coming in PostgreSQL 12). 但是,取决于您要执行的操作, jsonb具有很多搜索功能(SQL / JSON JSONPATH也包含在PostgreSQL 12中)。 This functionality isn't currently mapped in EF Core, but that shouldn't really stop you from using it via raw SQL. 该功能当前尚未在EF Core中进行映射,但这并不能真正阻止您通过原始SQL使用它。

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

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