ts_vector_update_trigger with JSONB column in postgresql / n



在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 使用它。

最新更新