From be0fe62244d462e913eedac1510e700f91455e45 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Tue, 15 Oct 2024 06:07:52 +0800 Subject: [PATCH] feat: support meta tags filter (#649) --- canal/canal.go | 3 +++ canal/event.go | 4 ++++ internal/model/subject.go | 1 + internal/pkg/cache/redis.go | 1 + internal/search/handle.go | 15 ++++++++++----- internal/search/index.go | 3 +++ internal/search/index_internal_test.go | 2 +- internal/subject/mysql_repository.go | 1 + openapi/v0.yaml | 8 ++++++++ 9 files changed, 32 insertions(+), 6 deletions(-) diff --git a/canal/canal.go b/canal/canal.go index bb33c7d27..985c7b4de 100644 --- a/canal/canal.go +++ b/canal/canal.go @@ -32,6 +32,7 @@ import ( "github.com/bangumi/server/internal/pkg/sys" "github.com/bangumi/server/internal/search" "github.com/bangumi/server/internal/subject" + "github.com/bangumi/server/internal/tag" "github.com/bangumi/server/web/session" ) @@ -64,6 +65,8 @@ func Main() error { subject.NewMysqlRepo, search.New, session.NewMysqlRepo, session.New, driver.NewS3, + tag.NewMysqlRepo, + newEventHandler, ), diff --git a/canal/event.go b/canal/event.go index e3cf10955..e75d9ffe5 100644 --- a/canal/event.go +++ b/canal/event.go @@ -28,6 +28,7 @@ import ( "github.com/bangumi/server/internal/model" "github.com/bangumi/server/internal/pkg/logger/log" "github.com/bangumi/server/internal/search" + "github.com/bangumi/server/internal/tag" "github.com/bangumi/server/web/session" ) @@ -37,6 +38,7 @@ func newEventHandler( session session.Manager, redis rueidis.Client, stream Stream, + tag tag.Repo, search search.Client, s3 *s3.Client, ) *eventHandler { @@ -48,6 +50,7 @@ func newEventHandler( s3: s3, stream: stream, log: log.Named("eventHandler"), + tag: tag, } } @@ -60,6 +63,7 @@ type eventHandler struct { stream Stream s3 *s3.Client // optional, check nil before use redis rueidis.Client + tag tag.Repo } func (e *eventHandler) start() error { diff --git a/internal/model/subject.go b/internal/model/subject.go index 626de64ee..256dc8e02 100644 --- a/internal/model/subject.go +++ b/internal/model/subject.go @@ -26,6 +26,7 @@ type Subject struct { Image string Summary string Name string + MetaTags string Date string // first release date NameCN string Infobox string diff --git a/internal/pkg/cache/redis.go b/internal/pkg/cache/redis.go index 3bfa9cc08..c73384055 100644 --- a/internal/pkg/cache/redis.go +++ b/internal/pkg/cache/redis.go @@ -85,6 +85,7 @@ func (c redisCache) Get(ctx context.Context, key string, value any) (bool, error func (c redisCache) MGet(ctx context.Context, keys []string, result any) error { results, err := c.ru.Do(ctx, c.ru.B().Mget().Key(keys...).Build()).ToArray() if err != nil { + //nolint:errorlint if err == rueidis.Nil { return nil } diff --git a/internal/search/handle.go b/internal/search/handle.go index 8a444ef92..4df44682f 100644 --- a/internal/search/handle.go +++ b/internal/search/handle.go @@ -58,11 +58,12 @@ type Req struct { } type ReqFilter struct { //nolint:musttag - Type []model.SubjectType `json:"type"` // or - Tag []string `json:"tag"` // and - AirDate []string `json:"air_date"` // and - Score []string `json:"rating"` // and - Rank []string `json:"rank"` // and + Type []model.SubjectType `json:"type"` // or + Tag []string `json:"tag"` // and + AirDate []string `json:"air_date"` // and + Score []string `json:"rating"` // and + Rank []string `json:"rank"` // and + MetaTags []string `json:"meta_tags"` // and // if NSFW subject is enabled NSFW null.Bool `json:"nsfw"` @@ -224,6 +225,10 @@ func filterToMeiliFilter(req ReqFilter) [][]string { filter = append(filter, []string{"nsfw = false"}) } + for _, tag := range req.MetaTags { + filter = append(filter, []string{"meta_tag = " + strconv.Quote(tag)}) + } + // AND for _, tag := range req.Tag { diff --git a/internal/search/index.go b/internal/search/index.go index 3c7c4433c..d185c5a49 100644 --- a/internal/search/index.go +++ b/internal/search/index.go @@ -16,6 +16,7 @@ package search import ( "strconv" + "strings" "github.com/bangumi/server/internal/model" "github.com/bangumi/server/pkg/wiki" @@ -28,6 +29,7 @@ import ( type subjectIndex struct { ID model.SubjectID `json:"id"` Tag []string `json:"tag,omitempty" filterable:"true"` + MetaTags []string `json:"meta_tag" filterable:"true"` Name string `json:"name" searchable:"true"` Aliases []string `json:"aliases,omitempty" searchable:"true"` Date int `json:"date,omitempty" filterable:"true" sortable:"true"` @@ -74,6 +76,7 @@ func extractSubject(s *model.Subject) subjectIndex { ID: s.ID, Name: s.Name, Aliases: extractAliases(s, w), + MetaTags: strings.Split(s.MetaTags, " "), Tag: tagNames, NSFW: s.NSFW, Type: s.TypeID, diff --git a/internal/search/index_internal_test.go b/internal/search/index_internal_test.go index a9d218441..5049c767b 100644 --- a/internal/search/index_internal_test.go +++ b/internal/search/index_internal_test.go @@ -25,7 +25,7 @@ func TestIndexFilter(t *testing.T) { t.Parallel() actual := *(getAttributes("filterable")) - expected := []string{"date", "score", "rank", "type", "nsfw", "tag"} + expected := []string{"date", "meta_tag", "score", "rank", "type", "nsfw", "tag"} sort.Strings(expected) sort.Strings(actual) diff --git a/internal/subject/mysql_repository.go b/internal/subject/mysql_repository.go index 64e9ccaf9..395979ebc 100644 --- a/internal/subject/mysql_repository.go +++ b/internal/subject/mysql_repository.go @@ -78,6 +78,7 @@ func ConvertDao(s *dao.Subject) (model.Subject, error) { ID: s.ID, Name: string(s.Name), NameCN: string(s.NameCN), + MetaTags: s.FieldMetaTags, TypeID: s.TypeID, Image: s.Image, PlatformID: s.Platform, diff --git a/openapi/v0.yaml b/openapi/v0.yaml index 13848f4ce..53cc49801 100644 --- a/openapi/v0.yaml +++ b/openapi/v0.yaml @@ -86,6 +86,14 @@ paths: items: $ref: "#/components/schemas/SubjectType" description: 条目类型,参照 `SubjectType` enum,多值之间为 `或` 的关系。 + meta_tags: + type: array + items: + type: string + example: + - 童年 + - 原创 + description: 公共标签。多个值之间为 `且` 关系。可以用 `-` 排除标签。比如 `-科幻` 可以排除科幻标签。 tag: type: array items: