diff --git a/search/pkg/search/index/index.go b/search/pkg/search/index/index.go index 4e2c43aac..ec8480c2d 100644 --- a/search/pkg/search/index/index.go +++ b/search/pkg/search/index/index.go @@ -30,10 +30,12 @@ import ( sprovider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" ) +// Index represents a bleve based search index type Index struct { bleveIndex bleve.Index } +// Entity describes an Entity stored in the index type Entity struct { RootID string Path string @@ -43,31 +45,34 @@ type Entity struct { Size uint64 } +// NewPersisted returns a new instance of Index with the data being persisted in the given directory func NewPersisted(path string) (*Index, error) { bi, err := bleve.New(path, BuildMapping()) if err != nil { return nil, err } - return &Index{ - bleveIndex: bi, - }, nil + return New(bi) } +// New returns a new instance of Index using the given bleve Index as the backend func New(bleveIndex bleve.Index) (*Index, error) { return &Index{ bleveIndex: bleveIndex, }, nil } +// Add adds a new entity to the Index func (i *Index) Add(ref *sprovider.Reference, ri *sprovider.ResourceInfo) error { entity := toEntity(ref, ri) return i.bleveIndex.Index(entity.ID, entity) } +// Remove removes an entity from the index func (i *Index) Remove(ri *sprovider.ResourceInfo) error { return i.bleveIndex.Delete(ri.Id.GetStorageId() + ":" + ri.Id.GetOpaqueId()) } +// Search searches the index according to the criteria specified in the given SearchIndexRequest func (i *Index) Search(ctx context.Context, req *search.SearchIndexRequest) (*search.SearchIndexResult, error) { query := bleve.NewConjunctionQuery( bleve.NewQueryStringQuery(req.Query), @@ -94,6 +99,7 @@ func (i *Index) Search(ctx context.Context, req *search.SearchIndexRequest) (*se }, nil } +// BuildMapping builds a bleve index mapping which can be used for indexing func BuildMapping() mapping.IndexMapping { indexMapping := bleve.NewIndexMapping() indexMapping.DefaultAnalyzer = keyword.Name diff --git a/search/pkg/search/index/index_test.go b/search/pkg/search/index/index_test.go index 795938528..37bf24468 100644 --- a/search/pkg/search/index/index_test.go +++ b/search/pkg/search/index/index_test.go @@ -152,10 +152,6 @@ var _ = Describe("Index", func() { }) }) - Describe("Scan", func() { - PIt("adds the given resource recursively") - }) - Describe("Index", func() { It("adds a resourceInfo to the index", func() { err := i.Add(ref, ri) diff --git a/search/pkg/search/provider/searchprovider_test.go b/search/pkg/search/provider/searchprovider_test.go index 6b3ee5a17..9f57fc45a 100644 --- a/search/pkg/search/provider/searchprovider_test.go +++ b/search/pkg/search/provider/searchprovider_test.go @@ -163,17 +163,17 @@ var _ = Describe("Searchprovider", func() { }, nil) indexClient.On("Search", mock.Anything, mock.Anything).Return(&search.SearchIndexResult{ Matches: []search.Match{ - search.Match{ + { Reference: &sprovider.Reference{ ResourceId: grantSpace.Root, - Path: "./grant/path/to/Foo.pdf", + Path: "./grant/path/to/Shared.pdf", }, Info: &sprovider.ResourceInfo{ Id: &sprovider.ResourceId{ StorageId: grantSpace.Root.StorageId, - OpaqueId: "grant-foo-id", + OpaqueId: "grant-shared-id", }, - Path: "Foo.pdf", + Path: "Shared.pdf", }, }, }, @@ -186,10 +186,10 @@ var _ = Describe("Searchprovider", func() { Expect(res).ToNot(BeNil()) Expect(len(res.Matches)).To(Equal(1)) match := res.Matches[0] - Expect(match.Info.Id.OpaqueId).To(Equal("grant-foo-id")) - Expect(match.Info.Path).To(Equal("Foo.pdf")) + Expect(match.Info.Id.OpaqueId).To(Equal("grant-shared-id")) + Expect(match.Info.Path).To(Equal("Shared.pdf")) Expect(match.Reference.ResourceId).To(Equal(grantSpace.Root)) - Expect(match.Reference.Path).To(Equal("./to/Foo.pdf")) + Expect(match.Reference.Path).To(Equal("./to/Shared.pdf")) indexClient.AssertCalled(GinkgoT(), "Search", mock.Anything, mock.MatchedBy(func(req *search.SearchIndexRequest) bool { return req.Query == "foo" && req.Reference.ResourceId == grantSpace.Root && req.Reference.Path == "./grant/path" @@ -208,17 +208,17 @@ var _ = Describe("Searchprovider", func() { return req.Reference.ResourceId == grantSpace.Root })).Return(&search.SearchIndexResult{ Matches: []search.Match{ - search.Match{ + { Reference: &sprovider.Reference{ ResourceId: grantSpace.Root, - Path: "./grant/path/to/Foo.pdf", + Path: "./grant/path/to/Shared.pdf", }, Info: &sprovider.ResourceInfo{ Id: &sprovider.ResourceId{ StorageId: grantSpace.Root.StorageId, - OpaqueId: "grant-foo-id", + OpaqueId: "grant-shared-id", }, - Path: "Foo.pdf", + Path: "Shared.pdf", }, }, }, @@ -227,7 +227,7 @@ var _ = Describe("Searchprovider", func() { return req.Reference.ResourceId == personalSpace.Root })).Return(&search.SearchIndexResult{ Matches: []search.Match{ - search.Match{ + { Reference: &sprovider.Reference{ ResourceId: personalSpace.Root, Path: "./path/to/Foo.pdf", @@ -250,8 +250,7 @@ var _ = Describe("Searchprovider", func() { Expect(res).ToNot(BeNil()) Expect(len(res.Matches)).To(Equal(2)) ids := []string{res.Matches[0].Info.Id.OpaqueId, res.Matches[1].Info.Id.OpaqueId} - Expect(ids).To(ConsistOf("foo-id", "grant-foo-id")) - + Expect(ids).To(ConsistOf("foo-id", "grant-shared-id")) }) }) }) diff --git a/search/pkg/search/search.go b/search/pkg/search/search.go index 28b3f592f..27acf38b0 100644 --- a/search/pkg/search/search.go +++ b/search/pkg/search/search.go @@ -27,35 +27,39 @@ import ( //go:generate mockery --name=ProviderClient //go:generate mockery --name=IndexClient +// SearchRequest represents a search request from a user to the search provider type SearchRequest struct { Query string } +// Match holds the information of a matched resource in a search type Match struct { Reference *sprovider.Reference Info *sprovider.ResourceInfo } +// SearchResult contains the matches being returned for a search type SearchResult struct { Matches []Match } -type SearchIndexRequest struct { - // Reference is not a list because the Path is used as a filter which is - // cut off in the matches by the provider. Multiple paths would not be - // distinguishable. - Reference *sprovider.Reference - Query string -} - -type SearchIndexResult struct { - Matches []Match -} - +// ProviderClient is the interface to the search provider service type ProviderClient interface { Search(ctx context.Context, req *SearchRequest) (*SearchResult, error) } +// SearchIndexRequest represents a search request to the index +type SearchIndexRequest struct { + Reference *sprovider.Reference + Query string +} + +// SearchResult contains the matches in the index being returned for a search +type SearchIndexResult struct { + Matches []Match +} + +// IndexClient is the interface to the search index type IndexClient interface { Search(ctx context.Context, req *SearchIndexRequest) (*SearchIndexResult, error) }