Skip to content

Commit

Permalink
internal/frontend: add symbol filters
Browse files Browse the repository at this point in the history
The # symbol filter is updated so that it can be used with any word,
instead of only as a prefix to indicate the user wants to search in
symbol mode.

For example, "#foo bar" was understood to mean, search for the query
string 'foo bar', in symbol search mode.

This is now understood to mean, search for the query string 'foo bar',
in symbol search mode, where 'foo' MUST match a symbol name.

This syntax allows users to specify which symbol to search for.

postgres.Search will support filters in the next CL.

For golang/go#44142

Change-Id: Ifb69f0d2745d68b5e0c28d734b48e58cc02c1819
Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/347610
Trust: Julie Qiu <julie@golang.org>
Run-TryBot: Julie Qiu <julie@golang.org>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
Reviewed-by: Jamal Carvalho <jamal@golang.org>
TryBot-Result: kokoro <noreply+kokoro@google.com>
  • Loading branch information
julieqiu committed Sep 9, 2021
1 parent 2704a0a commit 631c51d
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 11 deletions.
50 changes: 41 additions & 9 deletions internal/frontend/search.go
Expand Up @@ -43,11 +43,19 @@ func (s *Server) serveSearch(w http.ResponseWriter, r *http.Request, ds internal
}

ctx := r.Context()
query := searchQuery(r)
mode := searchMode(r)
query, filters := searchQueryAndFilters(r)
if !utf8.ValidString(query) {
return &serverError{status: http.StatusBadRequest}
}
if len(filters) > 1 {
return &serverError{
status: http.StatusBadRequest,
epage: &errorPage{
messageTemplate: template.MakeTrustedTemplate(
`<h3 class="Error-message">Search query contains more than one symbol.</h3>`),
},
}
}
if len(query) > maxSearchQueryLength {
return &serverError{
status: http.StatusBadRequest,
Expand Down Expand Up @@ -80,13 +88,17 @@ func (s *Server) serveSearch(w http.ResponseWriter, r *http.Request, ds internal
},
}
}

if path := searchRequestRedirectPath(ctx, ds, query); path != "" {
http.Redirect(w, r, path, http.StatusFound)
return nil
}

page, err := fetchSearchPage(ctx, db, query, pageParams, mode == searchModeSymbol)
var symbol string
if len(filters) > 0 {
symbol = filters[0]
}
mode := searchMode(r)
page, err := fetchSearchPage(ctx, db, query, symbol, pageParams, mode == searchModeSymbol)
if err != nil {
return fmt.Errorf("fetchSearchPage(ctx, db, %q): %v", query, err)
}
Expand Down Expand Up @@ -172,21 +184,21 @@ type subResult struct {

// fetchSearchPage fetches data matching the search query from the database and
// returns a SearchPage.
func fetchSearchPage(ctx context.Context, db *postgres.DB, query string,
func fetchSearchPage(ctx context.Context, db *postgres.DB, query, symbol string,
pageParams paginationParams, searchSymbols bool) (*SearchPage, error) {
maxResultCount := maxSearchOffset + pageParams.limit

offset := pageParams.offset()
if experiment.IsActive(ctx, internal.ExperimentSearchGrouping) {
// When using search grouping, do pageless search: always start from the beginning.
offset = 0
query = strings.TrimLeft(query, symbolSearchFilter)
}
dbresults, err := db.Search(ctx, query, postgres.SearchOptions{
MaxResults: pageParams.limit,
Offset: offset,
MaxResultCount: maxResultCount,
SearchSymbols: searchSymbols,
SymbolFilter: symbol,
})
if err != nil {
return nil, err
Expand Down Expand Up @@ -300,11 +312,11 @@ func searchMode(r *http.Request) string {
if !experiment.IsActive(r.Context(), internal.ExperimentSymbolSearch) {
return searchModePackage
}
q := searchQuery(r)
q := rawSearchQuery(r)
if strings.HasPrefix(q, symbolSearchFilter) {
return searchModeSymbol
}
mode := strings.TrimSpace(r.FormValue("m"))
mode := rawSearchMode(r)
if mode == searchModePackage {
return searchModePackage
}
Expand All @@ -317,10 +329,30 @@ func searchMode(r *http.Request) string {
return searchModePackage
}

func searchQuery(r *http.Request) string {
// searchQueryAndFilters returns the search query, trimmed of any filters, and
// the array of words that had a filter prefix.
func searchQueryAndFilters(r *http.Request) (string, []string) {
words := strings.Fields(rawSearchQuery(r))
var filters []string
for i := range words {
if strings.HasPrefix(words[i], symbolSearchFilter) {
words[i] = strings.TrimLeft(words[i], symbolSearchFilter)
filters = append(filters, words[i])
}
}
return strings.Join(words, " "), filters
}

// rawSearchQuery returns the exact search query by the user.
func rawSearchQuery(r *http.Request) string {
return strings.TrimSpace(r.FormValue("q"))
}

// rawSearchQuery returns the exact search mode from the URL request.
func rawSearchMode(r *http.Request) string {
return strings.TrimSpace(r.FormValue("m"))
}

// shouldDefaultToSymbolSearch reports whether the symbol search mode should
// default to symbol search mode based on the input.
func shouldDefaultToSymbolSearch(q string) bool {
Expand Down
2 changes: 1 addition & 1 deletion internal/frontend/search_test.go
Expand Up @@ -207,7 +207,7 @@ func TestFetchSearchPage(t *testing.T) {
},
} {
t.Run(test.name, func(t *testing.T) {
got, err := fetchSearchPage(ctx, testDB, test.query, paginationParams{limit: 20, page: 1}, false)
got, err := fetchSearchPage(ctx, testDB, test.query, "", paginationParams{limit: 20, page: 1}, false)
if err != nil {
t.Fatalf("fetchSearchPage(db, %q): %v", test.query, err)
}
Expand Down
2 changes: 1 addition & 1 deletion internal/frontend/server.go
Expand Up @@ -314,7 +314,7 @@ func (s *Server) licensePolicyHandler() http.HandlerFunc {

// newBasePage returns a base page for the given request and title.
func (s *Server) newBasePage(r *http.Request, title string) basePage {
q := searchQuery(r)
q := rawSearchQuery(r)
return basePage{
HTMLTitle: title,
Query: q,
Expand Down
3 changes: 3 additions & 0 deletions internal/postgres/search.go
Expand Up @@ -109,6 +109,9 @@ type SearchOptions struct {

// If true, perform a symbol search.
SearchSymbols bool

// SymbolFilter is the word in a search query with a # prefix.
SymbolFilter string
}

// SearchResult represents a single search result from SearchDocuments.
Expand Down

0 comments on commit 631c51d

Please sign in to comment.