mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-09-21 11:35:32 -04:00
refactor(search): run the bleve backend on the shared lowering pass
The bleve Creator runs query.Normalize before compiling; the compiler consumes a canonical AST with no field resolution or media-type special-casing.
This commit is contained in:
1 parent
bf7d04f7a1
commit
1cba974c1d
3 files changed
+21
-48
No files matched your search
@@ -22,6 +22,10 @@ func (c Creator[T]) Create(qs string) (T, error) {
|
||||
return t, err
|
||||
}
|
||||
|
||||
// shared KQL lowering pass: resolve field names + expand media-type aliases
|
||||
// once, so the compiler below sees only canonical field:value nodes.
|
||||
builderAst = query.Normalize(builderAst, query.ResolveField)
|
||||
|
||||
t, err = c.compiler.Compile(builderAst)
|
||||
if err != nil {
|
||||
return t, err
|
||||
|
||||
@@ -95,9 +95,11 @@ func walk(offset int, nodes []ast.Node) (bleveQuery.Query, int, error) {
|
||||
for i := offset; i < len(nodes); i++ {
|
||||
switch n := nodes[i].(type) {
|
||||
case *ast.StringNode:
|
||||
k := getField(n.Key)
|
||||
// keys are resolved and media-type expanded by normalize; MimeType
|
||||
// values are literal MIME types, so they skip the escaper.
|
||||
k := n.Key
|
||||
v := n.Value
|
||||
if k != "ID" && k != "Size" {
|
||||
if k != "ID" && k != "Size" && k != "MimeType" {
|
||||
v = bleveEscaper.Replace(n.Value)
|
||||
}
|
||||
|
||||
@@ -105,46 +107,7 @@ func walk(offset int, nodes []ast.Node) (bleveQuery.Query, int, error) {
|
||||
v = strings.ToLower(v)
|
||||
}
|
||||
|
||||
if k == "Type" {
|
||||
v = resourceType(v)
|
||||
}
|
||||
|
||||
var q bleveQuery.Query
|
||||
var group bool
|
||||
switch {
|
||||
case k == "Hidden":
|
||||
value, err := strconv.ParseBool(v)
|
||||
if err != nil {
|
||||
q = bleveQuery.NewMatchNoneQuery()
|
||||
break
|
||||
}
|
||||
|
||||
bq := bleveQuery.NewBoolFieldQuery(value)
|
||||
bq.SetField(k)
|
||||
q = bq
|
||||
case k == "MimeType":
|
||||
q, group = mimeType(k, v)
|
||||
if prev == nil {
|
||||
isGroup = group
|
||||
}
|
||||
case slices.Contains([]string{"Name", "Title"}, k) && strings.ContainsAny(n.Value, "*?"):
|
||||
patterns := []bleveQuery.Query{bleveQuery.NewQueryStringQuery(k + ".wildcard:" + v)}
|
||||
if !strings.HasSuffix(v, "*") {
|
||||
patterns = append(patterns, bleveQuery.NewQueryStringQuery(k+".wildcard:"+v+".*"))
|
||||
}
|
||||
|
||||
q = closed(bleveQuery.NewDisjunctionQuery(patterns))
|
||||
case n.Exact && !strings.ContainsAny(n.Value, "*?") && slices.Contains([]string{"Name", "Title"}, k):
|
||||
q = bleveQuery.NewQueryStringQuery(k + ".wildcard:" + v)
|
||||
case k == "Path" && !strings.ContainsAny(n.Value, "*?"):
|
||||
q = pathAndBelow(k, n.Value)
|
||||
case slices.Contains([]string{"Name", "Title", "Content"}, k) && !strings.ContainsAny(n.Value, "*?"):
|
||||
q = phrase(k, n.Value)
|
||||
case strings.Contains(n.Value, " ") && !strings.ContainsAny(n.Value, "*?"):
|
||||
q = phrase(k, n.Value)
|
||||
default:
|
||||
q = bleveQuery.NewQueryStringQuery(k + ":" + v)
|
||||
}
|
||||
q := bleveQuery.NewQueryStringQuery(k + ":" + v)
|
||||
|
||||
if prev == nil {
|
||||
prev = q
|
||||
@@ -157,7 +120,7 @@ func walk(offset int, nodes []ast.Node) (bleveQuery.Query, int, error) {
|
||||
End: bleveQuery.BleveQueryTime{},
|
||||
InclusiveStart: nil,
|
||||
InclusiveEnd: nil,
|
||||
FieldVal: getField(n.Key),
|
||||
FieldVal: n.Key,
|
||||
}
|
||||
|
||||
if n.Operator == nil {
|
||||
@@ -187,7 +150,14 @@ func walk(offset int, nodes []ast.Node) (bleveQuery.Query, int, error) {
|
||||
next = q
|
||||
}
|
||||
case *ast.NumberNode:
|
||||
q := numberRange(getField(n.Key), n.Operator, n.Value)
|
||||
var q bleveQuery.Query
|
||||
if field := getField(n.Key); slices.Contains([]string{"Size", "Type"}, field) {
|
||||
q = numberRange(field, n.Operator, n.Value)
|
||||
} else {
|
||||
// same answer as the OpenSearch backend: unknown numeric keys
|
||||
// match nothing instead of querying an arbitrary field
|
||||
q = bleveQuery.NewMatchNoneQuery()
|
||||
}
|
||||
if q == nil {
|
||||
continue
|
||||
}
|
||||
@@ -206,9 +176,7 @@ func walk(offset int, nodes []ast.Node) (bleveQuery.Query, int, error) {
|
||||
next = q
|
||||
}
|
||||
case *ast.GroupNode:
|
||||
if n.Key != "" {
|
||||
n = normalizeGroupingProperty(n)
|
||||
}
|
||||
// keys resolved and grouping property propagated in normalize
|
||||
q, _, err := walk(0, n.Nodes)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
|
||||
"github.com/blevesearch/bleve/v2/search/query"
|
||||
"github.com/opencloud-eu/opencloud/pkg/ast"
|
||||
searchquery "github.com/opencloud-eu/opencloud/services/search/pkg/query"
|
||||
tAssert "github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
@@ -590,7 +591,7 @@ func Test_compile(t *testing.T) {
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := compile(tt.args)
|
||||
got, err := compile(searchquery.Normalize(tt.args, searchquery.ResolveField))
|
||||
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("compile() error = %v, wantErr %v", err, tt.wantErr)
|
||||
|
||||
Reference in new issue
Block a user