internal/postgres: support 3 parallel multi-word searches
Symbol search now supports up to 3 parallel multi-word searches.
For example, previously "bee cmd command" would return 0 results, and
now it returns results for type Command in
github.com/beego/bee/cmd/commands.
A test is also added for the multiWordSearchCombinations function.
For golang/go#44142
Change-Id: I6cc6aa87655576c2d9c13dc90ea18d12d8b19c9c
Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/342472
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>
diff --git a/internal/postgres/symbolsearch.go b/internal/postgres/symbolsearch.go
index 04b3fa1..9ae9800 100644
--- a/internal/postgres/symbolsearch.go
+++ b/internal/postgres/symbolsearch.go
@@ -229,13 +229,18 @@
}
// If it is, try search for this word assuming it is the symbol name
// and everything else is a path element.
- symbolToPathTokens[w] = strings.Join(append(append([]string{}, words[0:i]...), words[i+1:]...), " & ")
+ pathTokens := append(append([]string{}, words[0:i]...), words[i+1:]...)
+ sort.Strings(pathTokens)
+ symbolToPathTokens[w] = strings.Join(pathTokens, " & ")
}
- if len(symbolToPathTokens) > 2 {
- // There are more than 2 possible searches that can be performed, so
- // just perform an OR query.
- orQuery := strings.Join(strings.Fields(q), " | ")
- return map[string]string{orQuery: orQuery}
+ if len(symbolToPathTokens) == 0 {
+ return nil
+ }
+ if len(symbolToPathTokens) > 3 {
+ // There are too many searches that can be performed, so
+ // return no results.
+ // TODO(golang/go#44142): Leave add support for an OR query.
+ return nil
}
return symbolToPathTokens
}
diff --git a/internal/postgres/symbolsearch_test.go b/internal/postgres/symbolsearch_test.go
index 0eb9004..2b9021f 100644
--- a/internal/postgres/symbolsearch_test.go
+++ b/internal/postgres/symbolsearch_test.go
@@ -136,3 +136,59 @@
m2.Packages()[0].Documentation[0].API = sample.API
MustInsertModule(ctx, t, testDB, m2)
}
+
+func TestMultiwordSearchCombinations(t *testing.T) {
+ for _, test := range []struct {
+ q string
+ want map[string]string
+ }{
+ {
+ q: "github.com foo",
+ want: map[string]string{
+ "foo": "github.com",
+ },
+ },
+ {
+ q: "julieqiu foo",
+ want: map[string]string{
+ "julieqiu": "foo",
+ "foo": "julieqiu",
+ },
+ },
+ {
+ q: "github.com/julieqiu foo",
+ want: map[string]string{
+ "foo": "github.com/julieqiu",
+ },
+ },
+ {
+ q: "github.com julieqiu/api-demo foo",
+ want: map[string]string{
+ "foo": "github.com & julieqiu/api-demo",
+ },
+ },
+ {
+ q: "github.com julieqiu/api-demo",
+ want: nil,
+ },
+ {
+ q: "bee cmd command",
+ want: map[string]string{
+ "bee": "cmd & command",
+ "cmd": "bee & command",
+ "command": "bee & cmd",
+ },
+ },
+ {
+ q: "bee beego cmd command",
+ want: nil,
+ },
+ } {
+ t.Run(test.q, func(t *testing.T) {
+ got := multiwordSearchCombinations(test.q)
+ if diff := cmp.Diff(test.want, got); diff != "" {
+ t.Errorf("mismatch (-want +got):\n%s", diff)
+ }
+ })
+ }
+}