From ca457d190d84f075040fbac8df739c71c9448c24 Mon Sep 17 00:00:00 2001 From: Anton Sattarov <dirty.mew@gmail.com> Date: Tue, 12 Dec 2023 14:20:42 +0100 Subject: [PATCH] add multi docs --- search/search.go | 50 +++++++++++++++++++++++++++++++++++++++++++ search/search_test.go | 31 +++++++++++++++++++++------ 2 files changed, 74 insertions(+), 7 deletions(-) diff --git a/search/search.go b/search/search.go index db4d8aec..9d59e428 100644 --- a/search/search.go +++ b/search/search.go @@ -52,3 +52,53 @@ func ItemTextSearch(query string, item *items.Item) (*items.Item, []string, erro return item, fields, nil } + +func ItemsTextSearch(query string, itms []*items.Item) ([]*items.Item, error) { + + index, err := bleve.NewMemOnly(bleve.NewIndexMapping()) + if err != nil { + return nil, err + } + + im := make(map[string]*items.Item, len(itms)) + for _, i := range itms { + im[i.ID] = i + if err = index.Index(i.ID, i); err != nil { + return nil, err + } + } + + searchRequest := bleve.NewSearchRequest(bleve.NewQueryStringQuery(query)) + searchRequest.Highlight = bleve.NewHighlight() + searchResult, err := index.Search(searchRequest) + if err != nil { + return nil, err + } + + if searchResult.Total == 0 { + return nil, errors.New("no results found") + } + + result := make([]*items.Item, 0, len(searchResult.Hits)) + for _, hint := range searchResult.Hits { + item, ok := im[hint.ID] + if !ok { + return nil, errors.New("search result not match item") + } + + for key, value := range hint.Fragments { + key = strings.TrimPrefix(key, "data.") + + if key == "id" { + item.Data[key] = value + } + + if err = item.Set(key, value); err != nil { + return nil, err + } + } + result = append(result, item) + } + + return result, nil +} diff --git a/search/search_test.go b/search/search_test.go index 02526938..260a6a16 100644 --- a/search/search_test.go +++ b/search/search_test.go @@ -2,13 +2,14 @@ package search import ( "encoding/json" + "strconv" "testing" "git.perx.ru/perxis/perxis-go/pkg/items" + "github.com/stretchr/testify/require" ) -func BenchmarkItemTextSearch(b *testing.B) { - +func BenchmarkTextSearch(b *testing.B) { jsonStr := `{ "common": { "environment_id": "cjfmbiaeibkll33i38g0", @@ -35,14 +36,30 @@ func BenchmarkItemTextSearch(b *testing.B) { } }` - item := &items.Item{ID: "1"} query := "cjfmbiaeibkll33i38fg" d := map[string]interface{}{} _ = json.Unmarshal([]byte(jsonStr), &d) - item.Data = d - for i := 0; i < b.N; i++ { - v, f, err := ItemTextSearch(query, item) - _, _, _ = v, f, err + b.Run("Item", func(b *testing.B) { + b.ReportAllocs() + b.ResetTimer() + for i := 0; i < b.N; i++ { + _, _, err := ItemTextSearch(query, &items.Item{ID: "1", Data: d}) + require.NoError(b, err) + } + }) + + var itms []*items.Item + for i := 0; i < 100; i++ { + itms = append(itms, &items.Item{ID: strconv.Itoa(i), Data: d}) } + + b.Run("Items", func(b *testing.B) { + b.ReportAllocs() + b.ResetTimer() + for i := 0; i < b.N; i++ { + _, err := ItemsTextSearch(query, itms) + require.NoError(b, err) + } + }) } -- GitLab