♻️ Better way to vectorize quill delta

This commit is contained in:
LittleSheep 2025-05-03 00:06:01 +08:00
parent 17de9a0f23
commit 46054dfb7b
2 changed files with 58 additions and 5 deletions

View File

@ -134,7 +134,6 @@ public class AppDatabase(
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<Post.Post>()
.HasGeneratedTsVectorColumn(p => p.SearchVector, "simple", p => new { p.Title, p.Description, p.Content })
.HasIndex(p => p.SearchVector)
.HasMethod("GIN");
modelBuilder.Entity<Post.Post>()
@ -193,6 +192,16 @@ public class AppDatabase(
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<Chat.MessageStatus>()
.HasKey(e => new { e.MessageId, e.SenderId });
modelBuilder.Entity<Chat.Message>()
.HasOne(m => m.ForwardedMessage)
.WithMany()
.HasForeignKey(m => m.ForwardedMessageId)
.OnDelete(DeleteBehavior.Restrict);
modelBuilder.Entity<Chat.Message>()
.HasOne(m => m.RepliedMessage)
.WithMany()
.HasForeignKey(m => m.RepliedMessageId)
.OnDelete(DeleteBehavior.Restrict);
// Automatically apply soft-delete filter to all entities inheriting BaseModel
foreach (var entityType in modelBuilder.Model.GetEntityTypes())

View File

@ -74,6 +74,9 @@ public class PostService(AppDatabase db, FileService fs, ActivityService act)
List<string>? categories = null
)
{
if (post.Empty)
throw new InvalidOperationException("Cannot create a post with barely no content.");
if (post.PublishedAt is not null)
{
if (post.PublishedAt.Value.ToDateTimeUtc() < DateTime.UtcNow)
@ -118,8 +121,27 @@ public class PostService(AppDatabase db, FileService fs, ActivityService act)
throw new InvalidOperationException("Categories contains one or more categories that wasn't exists.");
}
if (post.Empty)
throw new InvalidOperationException("Cannot create a post with barely no content.");
// Vectorize the quill delta content
if (post.Content?.RootElement is { ValueKind: JsonValueKind.Array })
{
var searchTextBuilder = new System.Text.StringBuilder();
if (!string.IsNullOrWhiteSpace(post.Title))
searchTextBuilder.AppendLine(post.Title);
if (!string.IsNullOrWhiteSpace(post.Description))
searchTextBuilder.AppendLine(post.Description);
foreach (var element in post.Content.RootElement.EnumerateArray())
{
if (element is { ValueKind: JsonValueKind.Object } &&
element.TryGetProperty("insert", out var insertProperty) &&
insertProperty.ValueKind == JsonValueKind.String)
{
searchTextBuilder.Append(insertProperty.GetString());
}
}
post.SearchVector = EF.Functions.ToTsVector(searchTextBuilder.ToString().Trim());
}
// TODO Notify the subscribers
@ -140,6 +162,9 @@ public class PostService(AppDatabase db, FileService fs, ActivityService act)
Instant? publishedAt = null
)
{
if (post.Empty)
throw new InvalidOperationException("Cannot edit a post to barely no content.");
post.EditedAt = Instant.FromDateTimeUtc(DateTime.UtcNow);
if (publishedAt is not null)
@ -196,8 +221,27 @@ public class PostService(AppDatabase db, FileService fs, ActivityService act)
throw new InvalidOperationException("Categories contains one or more categories that wasn't exists.");
}
if (post.Empty)
throw new InvalidOperationException("Cannot edit a post to barely no content.");
// Vectorize the quill delta content
if (post.Content?.RootElement is { ValueKind: JsonValueKind.Array })
{
var searchTextBuilder = new System.Text.StringBuilder();
if (!string.IsNullOrWhiteSpace(post.Title))
searchTextBuilder.AppendLine(post.Title);
if (!string.IsNullOrWhiteSpace(post.Description))
searchTextBuilder.AppendLine(post.Description);
foreach (var element in post.Content.RootElement.EnumerateArray())
{
if (element is { ValueKind: JsonValueKind.Object } &&
element.TryGetProperty("insert", out var insertProperty) &&
insertProperty.ValueKind == JsonValueKind.String)
{
searchTextBuilder.Append(insertProperty.GetString());
}
}
post.SearchVector = EF.Functions.ToTsVector(searchTextBuilder.ToString().Trim());
}
db.Update(post);
await db.SaveChangesAsync();