From 6a1a8e796f4371168cff8921bdabbcc52c91b973 Mon Sep 17 00:00:00 2001 From: Miroslav Cvetic Date: Tue, 4 Mar 2025 14:07:49 +0100 Subject: [PATCH] feat: support filter by multiple values --- pkg/api/api.go | 2 +- pkg/api/utils.go | 34 ++++++++++++++++++---------------- pkg/interface.go | 2 +- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/pkg/api/api.go b/pkg/api/api.go index 6617fc2..faaa021 100644 --- a/pkg/api/api.go +++ b/pkg/api/api.go @@ -270,7 +270,7 @@ func (b *BaseAPI[indexDocument, returnType]) SimpleSearch( ctx context.Context, index pkgtypesense.IndexID, q string, - filterBy map[string]string, + filterBy map[string][]string, page, perPage int, sortBy string, ) ([]returnType, pkgtypesense.Scores, error) { diff --git a/pkg/api/utils.go b/pkg/api/utils.go index 7a3a504..2efabeb 100644 --- a/pkg/api/utils.go +++ b/pkg/api/utils.go @@ -18,7 +18,7 @@ import ( // for the typesense search API without any knowledge of the typesense API func buildSearchParams( q string, - filterBy map[string]string, + filterBy map[string][]string, // Updated to allow multiple values per field page, perPage int, sortBy string, ) *api.SearchCollectionParams { @@ -36,31 +36,33 @@ func buildSearchParams( return parameters } -func formatFilterQuery(filterBy map[string]string) string { +func formatFilterQuery(filterBy map[string][]string) string { if filterBy == nil { return "" } - filterByString := []string{} - for key, value := range filterBy { - filterByString = append(filterByString, key+":="+value) + + var filterClauses []string + for key, values := range filterBy { + if len(values) == 1 { + // Single value → Use `:=` operator + filterClauses = append(filterClauses, fmt.Sprintf("%s:=\"%s\"", key, values[0])) + } else { + // Multiple values → Use `["val1","val2"]` array syntax + formattedValues := []string{} + for _, v := range values { + formattedValues = append(formattedValues, fmt.Sprintf("\"%s\"", v)) + } + filterClauses = append(filterClauses, fmt.Sprintf("%s:[%s]", key, strings.Join(formattedValues, ","))) + } } - return strings.Join(filterByString, "&&") + + return strings.Join(filterClauses, " && ") // AND conditions by default } func (b *BaseAPI[indexDocument, returnType]) generateRevisionID() pkgtypesense.RevisionID { return pkgtypesense.RevisionID(time.Now().Format("2006-01-02-15-04")) // "YYYY-MM-DD-HH-MM" } -func getLatestRevisionID(revisions map[pkgtypesense.IndexID]pkgtypesense.RevisionID) pkgtypesense.RevisionID { - var latest pkgtypesense.RevisionID - for _, rev := range revisions { - if rev > latest { - latest = rev - } - } - return latest -} - func formatCollectionName(indexID pkgtypesense.IndexID, revisionID pkgtypesense.RevisionID) string { return fmt.Sprintf("%s-%s", indexID, revisionID) } diff --git a/pkg/interface.go b/pkg/interface.go index 3865237..7573f87 100644 --- a/pkg/interface.go +++ b/pkg/interface.go @@ -21,7 +21,7 @@ type API[indexDocument any, returnType any] interface { ctx context.Context, index IndexID, q string, - filterBy map[string]string, + filterBy map[string][]string, page, perPage int, sortBy string, ) ([]returnType, Scores, error)