In EFCore + npgsql, using postgresql 10, I want to create a tsvector column to allow full text search of some fields in a model:
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:
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:
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. Is it possible to achieve what I'm looking for? I'm relatively new to postgresql, npgsql and EFCore.