From d49c960be524790b533bb86fa41d7ff7de5cad1b Mon Sep 17 00:00:00 2001 From: LittleSheep Date: Sun, 8 Dec 2024 14:09:34 +0800 Subject: [PATCH] :sparkles: Better search api allow searching with tags or categories only --- pkg/internal/http/api/posts_api.go | 12 ++++++------ pkg/internal/services/posts.go | 13 +++++++++++-- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/pkg/internal/http/api/posts_api.go b/pkg/internal/http/api/posts_api.go index 0cf10bc..2f3e88c 100644 --- a/pkg/internal/http/api/posts_api.go +++ b/pkg/internal/http/api/posts_api.go @@ -40,11 +40,11 @@ func universalPostFilter(c *fiber.Ctx, tx *gorm.DB) (*gorm.DB, error) { tx = tx.Where("publisher_id = ?", author.ID) } - if len(c.Query("category")) > 0 { - tx = services.FilterPostWithCategory(tx, c.Query("category")) + if len(c.Query("categories")) > 0 { + tx = services.FilterPostWithCategory(tx, c.Query("categories")) } - if len(c.Query("tag")) > 0 { - tx = services.FilterPostWithTag(tx, c.Query("tag")) + if len(c.Query("tags")) > 0 { + tx = services.FilterPostWithTag(tx, c.Query("tags")) } if len(c.Query("type")) > 0 { @@ -103,8 +103,8 @@ func searchPost(c *fiber.Ctx) error { tx := database.C probe := c.Query("probe") - if len(probe) == 0 { - return fiber.NewError(fiber.StatusBadRequest, "probe is required") + if len(probe) == 0 && len(c.Query("tags")) == 0 && len(c.Query("categories")) == 0 { + return fiber.NewError(fiber.StatusBadRequest, "search term (probe, tags or categories) is required") } tx = services.FilterPostWithFuzzySearch(tx, probe) diff --git a/pkg/internal/services/posts.go b/pkg/internal/services/posts.go index 826baa5..5201da7 100644 --- a/pkg/internal/services/posts.go +++ b/pkg/internal/services/posts.go @@ -9,6 +9,7 @@ import ( authm "git.solsynth.dev/hypernet/passport/pkg/authkit/models" "regexp" "strconv" + "strings" "time" "git.solsynth.dev/hypernet/interactive/pkg/internal/database" @@ -59,13 +60,17 @@ func FilterPostWithUserContext(tx *gorm.DB, user *authm.Account) *gorm.DB { func FilterPostWithCategory(tx *gorm.DB, alias string) *gorm.DB { return tx.Joins("JOIN post_categories ON posts.id = post_categories.post_id"). Joins("JOIN categories ON categories.id = post_categories.category_id"). - Where("categories.alias = ?", alias) + Where("categories.alias IN ?", strings.Split(alias, ",")). + Distinct("posts.id") } func FilterPostWithTag(tx *gorm.DB, alias string) *gorm.DB { + aliases := strings.Split(alias, ",") return tx.Joins("JOIN post_tags ON posts.id = post_tags.post_id"). Joins("JOIN tags ON tags.id = post_tags.tag_id"). - Where("tags.alias = ?", alias) + Where("tags.alias IN ?", aliases). + Group("posts.id"). + Having("COUNT(DISTINCT tags.id) = ?", len(aliases)) } func FilterPostWithType(tx *gorm.DB, t string) *gorm.DB { @@ -103,6 +108,10 @@ func FilterPostDraft(tx *gorm.DB) *gorm.DB { } func FilterPostWithFuzzySearch(tx *gorm.DB, probe string) *gorm.DB { + if len(probe) == 0 { + return tx + } + probe = "%" + probe + "%" return tx. Where("? AND body->>'content' ILIKE ?", gorm.Expr("body ? 'content'"), probe).