From 46054dfb7b740d786499099f151b2f6960837be8 Mon Sep 17 00:00:00 2001 From: LittleSheep Date: Sat, 3 May 2025 00:06:01 +0800 Subject: [PATCH] :recycle: Better way to vectorize quill delta --- DysonNetwork.Sphere/AppDatabase.cs | 11 +++++- DysonNetwork.Sphere/Post/PostService.cs | 52 +++++++++++++++++++++++-- 2 files changed, 58 insertions(+), 5 deletions(-) diff --git a/DysonNetwork.Sphere/AppDatabase.cs b/DysonNetwork.Sphere/AppDatabase.cs index 6df65a4..9ba856e 100644 --- a/DysonNetwork.Sphere/AppDatabase.cs +++ b/DysonNetwork.Sphere/AppDatabase.cs @@ -134,7 +134,6 @@ public class AppDatabase( .OnDelete(DeleteBehavior.Cascade); modelBuilder.Entity() - .HasGeneratedTsVectorColumn(p => p.SearchVector, "simple", p => new { p.Title, p.Description, p.Content }) .HasIndex(p => p.SearchVector) .HasMethod("GIN"); modelBuilder.Entity() @@ -193,6 +192,16 @@ public class AppDatabase( .OnDelete(DeleteBehavior.Cascade); modelBuilder.Entity() .HasKey(e => new { e.MessageId, e.SenderId }); + modelBuilder.Entity() + .HasOne(m => m.ForwardedMessage) + .WithMany() + .HasForeignKey(m => m.ForwardedMessageId) + .OnDelete(DeleteBehavior.Restrict); + modelBuilder.Entity() + .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()) diff --git a/DysonNetwork.Sphere/Post/PostService.cs b/DysonNetwork.Sphere/Post/PostService.cs index 4d44881..6cfc0ec 100644 --- a/DysonNetwork.Sphere/Post/PostService.cs +++ b/DysonNetwork.Sphere/Post/PostService.cs @@ -74,6 +74,9 @@ public class PostService(AppDatabase db, FileService fs, ActivityService act) List? 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();