diff --git a/changelog/unreleased/fix-bleve-search.md b/changelog/unreleased/fix-bleve-search.md new file mode 100644 index 0000000000..5e0abea8b6 --- /dev/null +++ b/changelog/unreleased/fix-bleve-search.md @@ -0,0 +1,7 @@ +Bugfix: Fix the kql-bleve search + +We fixed the issue when 500 on searches that contain ":". Added the characters escaping according to https://blevesearch.com/docs/Query-String-Query/ + + +https://github.com/owncloud/ocis/pull/7290 +https://github.com/owncloud/ocis/issues/7282 diff --git a/services/search/pkg/query/bleve/compiler.go b/services/search/pkg/query/bleve/compiler.go index 5876f0b81a..c7b1c70d82 100644 --- a/services/search/pkg/query/bleve/compiler.go +++ b/services/search/pkg/query/bleve/compiler.go @@ -26,6 +26,34 @@ var _fields = map[string]string{ "hidden": "Hidden", } +// The following quoted string enumerates the characters which may be escaped: "+-=&|>`, `\>`, + `<`, `\<`, + `!`, `\!`, + `(`, `\(`, + `)`, `\)`, + `{`, `\{`, + `}`, `\}`, + `{`, `\}`, + `[`, `\[`, + `]`, `\]`, + `^`, `\^`, + `"`, `\"`, + `~`, `\~`, + `:`, `\:`, + `\`, `\\`, + `/`, `\/`, + ` `, `\ `, +) + // Compiler represents a KQL query search string to the bleve query formatter. type Compiler struct{} @@ -58,7 +86,10 @@ func walk(offset int, nodes []ast.Node) (bleveQuery.Query, int, error) { switch n := nodes[i].(type) { case *ast.StringNode: k := getField(n.Key) - v := strings.ReplaceAll(n.Value, " ", `\ `) + v := n.Value + if k != "ID" && k != "Size" { + v = bleveEscaper.Replace(n.Value) + } if k != "Hidden" { v = strings.ToLower(v) diff --git a/services/search/pkg/query/bleve/compiler_test.go b/services/search/pkg/query/bleve/compiler_test.go index 4743a069a8..7a36b647dc 100644 --- a/services/search/pkg/query/bleve/compiler_test.go +++ b/services/search/pkg/query/bleve/compiler_test.go @@ -341,6 +341,18 @@ func Test_compile(t *testing.T) { }), wantErr: false, }, + { + name: `John Smith`, + args: &ast.Ast{ + Nodes: []ast.Node{ + &ast.StringNode{Value: "John Smith +-=&|>\<\!\(\)\{\}\[\]\^\"\~\:\ `), + }), + wantErr: false, + }, } assert := tAssert.New(t) @@ -357,3 +369,34 @@ func Test_compile(t *testing.T) { }) } } + +func Test_escape(t *testing.T) { + type args struct { + str string + } + tests := []struct { + name string + args args + want string + }{ + { + name: "all escaped", + args: args{ + `+-=&|>\<\!\(\)\{\}\[\]\^\"\~\:\\\/\ `, + }, + { + name: "no one escaped", + args: args{ + `@#$%`, + }, + want: `@#$%`, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tAssert.Equalf(t, tt.want, bleveEscaper.Replace(tt.args.str), "bleveEscaper(%v)", tt.args.str) + }) + } +}