From ef0727860ad652e0836b74d4a94e840f5102e243 Mon Sep 17 00:00:00 2001 From: Mike Goldin Date: Thu, 15 Oct 2020 09:03:18 -0400 Subject: Add full-text search support in the ls command --- cache/repo_cache.go | 21 ++----------- cache/repo_cache_bug.go | 84 ++++++++++++++++++++++++++++++------------------- 2 files changed, 54 insertions(+), 51 deletions(-) diff --git a/cache/repo_cache.go b/cache/repo_cache.go index 632469e4..8bce3d8c 100644 --- a/cache/repo_cache.go +++ b/cache/repo_cache.go @@ -207,9 +207,9 @@ func (c *RepoCache) buildCache() error { allBugs := bug.ReadAllLocal(c.repo) - err := c.ensureBleveIndex() + err := c.createBleveIndex() if err != nil { - return fmt.Errorf("Unable to create or open search cache. Error: %v", err) + return fmt.Errorf("Unable to create search cache. Error: %v", err) } for b := range allBugs { @@ -230,23 +230,6 @@ func (c *RepoCache) buildCache() error { return nil } -func (c *RepoCache) addBugToSearchIndex(snap *bug.Snapshot) error { - searchableBug := struct { - Text []string - }{} - - for _, comment := range snap.Comments { - searchableBug.Text = append(searchableBug.Text, comment.Message) - } - - err := c.searchCache.Index(snap.Id().String(), searchableBug) - if err != nil { - return err - } - - return nil -} - func repoLockFilePath(repo repository.Repo) string { return path.Join(repo.GetPath(), "git-bug", lockfile) } diff --git a/cache/repo_cache_bug.go b/cache/repo_cache_bug.go index dd833b46..4afcbe70 100644 --- a/cache/repo_cache_bug.go +++ b/cache/repo_cache_bug.go @@ -8,6 +8,7 @@ import ( "os" "path" "sort" + "strings" "time" "github.com/MichaelMure/git-bug/bug" @@ -85,10 +86,15 @@ func (c *RepoCache) loadBugCache() error { return fmt.Errorf("unknown cache format version %v", aux.Version) } - err = c.ensureBleveIndex() + c.bugExcerpts = aux.Excerpts + + blevePath := searchCacheDirPath(c.repo) + searchCache, err := bleve.Open(blevePath) if err != nil { - return fmt.Errorf("Unable to create or open search cache. Error: %v", err) + return fmt.Errorf("Unable to open search cache. Error: %v", err) } + c.searchCache = searchCache + count, err := c.searchCache.DocCount() if err != nil { return err @@ -97,33 +103,20 @@ func (c *RepoCache) loadBugCache() error { return fmt.Errorf("count mismatch between bleve and bug excerpts") } - c.bugExcerpts = aux.Excerpts return nil } -func (c *RepoCache) ensureBleveIndex() error { +func (c *RepoCache) createBleveIndex() error { blevePath := searchCacheDirPath(c.repo) - // Try to open the bleve index. If there is _any_ error, whether it be that - // the bleve index does not exist or is corrupt, handle that by nuking the - // bleve index and recreating it. - bleveIndex, err := bleve.Open(blevePath) - if err != nil { - // If the index does not exist, we don't care. We're going to create it - // next. - _ = os.RemoveAll(blevePath) - - mapping := bleve.NewIndexMapping() - dir := searchCacheDirPath(c.repo) - - bleveIndex, err := bleve.New(dir, mapping) - if err != nil { - return err - } + _ = os.RemoveAll(blevePath) - c.searchCache = bleveIndex + mapping := bleve.NewIndexMapping() + dir := searchCacheDirPath(c.repo) - return nil + bleveIndex, err := bleve.New(dir, mapping) + if err != nil { + return err } c.searchCache = bleveIndex @@ -309,19 +302,27 @@ func (c *RepoCache) QueryBugs(q *query.Query) []entity.Id { matcher := compileMatcher(q.Filters) var filtered []*BugExcerpt + var foundBySearch map[entity.Id]*BugExcerpt - //if q.Search != nil { - // booleanQuery := bleve.NewBooleanQuery() - // for _, term := range q.Search { - // query := bleve.NewMatchQuery(term) - // booleanQuery.AddMust(query) - // } + if q.Search != nil { + foundBySearch = map[entity.Id]*BugExcerpt{} - // search := bleve.NewSearchRequest(booleanQuery) - // searchResults, _ := c.searchCache.Search(search) - //} + query := bleve.NewQueryStringQuery(strings.Join(q.Search, " ")) - for _, excerpt := range c.bugExcerpts { + search := bleve.NewSearchRequest(query) + searchResults, err := c.searchCache.Search(search) + if err != nil { + panic("bleve search failed") + } + + for _, hit := range searchResults.Hits { + foundBySearch[entity.Id(hit.ID)] = c.bugExcerpts[entity.Id(hit.ID)] + } + } else { + foundBySearch = c.bugExcerpts + } + + for _, excerpt := range foundBySearch { if matcher.Match(excerpt, c) { filtered = append(filtered, excerpt) } @@ -488,3 +489,22 @@ func (c *RepoCache) RemoveBug(prefix string) error { return c.writeBugCache() } + +func (c *RepoCache) addBugToSearchIndex(snap *bug.Snapshot) error { + searchableBug := struct { + Text []string + }{} + + for _, comment := range snap.Comments { + searchableBug.Text = append(searchableBug.Text, comment.Message) + } + + searchableBug.Text = append(searchableBug.Text, snap.Title) + + err := c.searchCache.Index(snap.Id().String(), searchableBug) + if err != nil { + return err + } + + return nil +} -- cgit