internal/postgres,tests/search: use filters

postgres.Search now supports symbol and package filters.

tests/search is also updated to match this change.

For golang/go#44142

Change-Id: Icbd05b99ea3a74956d5726e03c8767ab6062d133
Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/347611
Trust: Julie Qiu <julie@golang.org>
Run-TryBot: Julie Qiu <julie@golang.org>
TryBot-Result: kokoro <noreply+kokoro@google.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
Reviewed-by: Jamal Carvalho <jamal@golang.org>
diff --git a/internal/postgres/symbolsearch.go b/internal/postgres/symbolsearch.go
index 826ac31..d5d59fe 100644
--- a/internal/postgres/symbolsearch.go
+++ b/internal/postgres/symbolsearch.go
@@ -109,7 +109,7 @@
 	case symbolsearch.InputTypeOneDot:
 		results, err = runSymbolSearchOneDot(ctx, db.db, q, limit)
 	case symbolsearch.InputTypeMultiWord:
-		results, err = runSymbolSearchMultiWord(ctx, db.db, q, limit)
+		results, err = runSymbolSearchMultiWord(ctx, db.db, q, limit, opts.SymbolFilter)
 	case symbolsearch.InputTypeNoDot:
 		results, err = runSymbolSearch(ctx, db.db, symbolsearch.SearchTypeSymbol, q, limit)
 	case symbolsearch.InputTypeTwoDots:
@@ -152,11 +152,13 @@
 }
 
 // runSymbolSearchMultiWord executes a symbol search for SearchTypeMultiWord.
-func runSymbolSearchMultiWord(ctx context.Context, ddb *database.DB, q string, limit int) (_ []*SearchResult, err error) {
-	defer derrors.Wrap(&err, "runSymbolSearchMultiWord(ctx, ddb, query, %q, %d)", q, limit)
+func runSymbolSearchMultiWord(ctx context.Context, ddb *database.DB, q string, limit int,
+	symbolFilter string) (_ []*SearchResult, err error) {
+	defer derrors.Wrap(&err, "runSymbolSearchMultiWord(ctx, ddb, query, %q, %d, %q)",
+		q, limit, symbolFilter)
 	defer middleware.ElapsedStat(ctx, "runSymbolSearchMultiWord")()
 
-	symbolToPathTokens := multiwordSearchCombinations(q)
+	symbolToPathTokens := multiwordSearchCombinations(q, symbolFilter)
 	if len(symbolToPathTokens) == 0 {
 		// There are no words in the query that could be a symbol name.
 		return nil, derrors.NotFound
@@ -219,7 +221,7 @@
 // It is assumed that the symbol name is always 1 word. For example, if the
 // user wants sql.DB.Begin, "sql DB.Begin", "sql Begin", or "sql DB" will all
 // be return the relevant result, but "sql DB Begin" will not.
-func multiwordSearchCombinations(q string) map[string]string {
+func multiwordSearchCombinations(q, symbolFilter string) map[string]string {
 	words := strings.Fields(q)
 	symbolToPathTokens := map[string]string{}
 	for i, w := range words {
@@ -227,6 +229,11 @@
 		if strings.Contains(w, "/") || strings.Contains(w, "-") || commonHostnames[w] {
 			continue
 		}
+		// A symbolFilter was used, and this word does not match match it, so
+		// it can't be the symbol name.
+		if symbolFilter != "" && w != symbolFilter {
+			continue
+		}
 		// If it is, try search for this word assuming it is the symbol name
 		// and everything else is a path element.
 		pathTokens := append(append([]string{}, words[0:i]...), words[i+1:]...)
diff --git a/internal/postgres/symbolsearch_test.go b/internal/postgres/symbolsearch_test.go
index 5c908b4..0b69728 100644
--- a/internal/postgres/symbolsearch_test.go
+++ b/internal/postgres/symbolsearch_test.go
@@ -143,8 +143,8 @@
 
 func TestMultiwordSearchCombinations(t *testing.T) {
 	for _, test := range []struct {
-		q    string
-		want map[string]string
+		q, filter string
+		want      map[string]string
 	}{
 		{
 			q: "github.com foo",
@@ -187,9 +187,16 @@
 			q:    "bee beego cmd command",
 			want: nil,
 		},
+		{
+			q:      "bee beego cmd command",
+			filter: "command",
+			want: map[string]string{
+				"command": "bee & beego & cmd",
+			},
+		},
 	} {
 		t.Run(test.q, func(t *testing.T) {
-			got := multiwordSearchCombinations(test.q)
+			got := multiwordSearchCombinations(test.q, test.filter)
 			if diff := cmp.Diff(test.want, got); diff != "" {
 				t.Errorf("mismatch (-want +got):\n%s", diff)
 			}