diff --git a/search/search.go b/search/search.go
index db4d8aecedb4f7f45564a14980e48b5946a69ca8..9d59e42817d273b13cf22459a562008b6414e8ae 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 025269383ed08115dbeb9eea46c54a40a98548fa..260a6a16592b66fe81566b52b2b010dc72abcb2b 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)
+		}
+	})
 }