enhancement(search): implement non bool query compilation

This commit is contained in:
fschade
2025-07-30 19:48:26 +02:00
parent 098a220626
commit 4d5a5dde4b
2 changed files with 45 additions and 23 deletions

View File

@@ -19,6 +19,7 @@ func (k *KQL) Compile(tree *ast.Ast) (Builder, error) {
if err != nil {
return nil, err
}
return q, nil
}
@@ -62,12 +63,27 @@ func (k *KQL) getOperatorValueAt(nodes []ast.Node, i int) string {
return ""
}
func (k *KQL) getBuilder(node ast.Node) (Builder, error) {
var builder Builder
switch node := node.(type) {
case *ast.StringNode:
builder = NewTermQuery[string](k.getFieldName(node.Key)).Value(node.Value)
case *ast.GroupNode:
group, err := k.compile(node.Nodes)
if err != nil {
return nil, fmt.Errorf("failed to build group: %w", err)
}
builder = group
}
return builder, nil
}
func (k *KQL) compile(nodes []ast.Node) (Builder, error) {
boolQuery := NewBoolQuery()
add := boolQuery.Must
for i, node := range nodes {
for i, node := range nodes {
prevOp := k.getOperatorValueAt(nodes, i-1)
nextOp := k.getOperatorValueAt(nodes, i+1)
@@ -78,15 +94,21 @@ func (k *KQL) compile(nodes []ast.Node) (Builder, error) {
add = boolQuery.Must
}
switch node := node.(type) {
case *ast.StringNode:
add(NewTermQuery[string](k.getFieldName(node.Key)).Value(node.Value))
case *ast.GroupNode:
group, err := k.compile(node.Nodes)
if err != nil {
return nil, fmt.Errorf("failed to build group: %w", err)
}
add(group)
if _, ok := node.(*ast.OperatorNode); ok {
// operatorNodes are not builders, so we skip them
continue
}
builder, err := k.getBuilder(node)
if err != nil {
return nil, fmt.Errorf("failed to get builder for node %T: %w", node, err)
}
switch {
case len(nodes) == 1:
return builder, nil
default:
add(builder)
}
}

View File

@@ -19,10 +19,7 @@ func TestKQL_Compile(t *testing.T) {
&ast.StringNode{Value: "moby di*"},
},
},
want: opensearch.NewBoolQuery().
Must(
opensearch.NewTermQuery[string]("Name").Value("moby di*"),
),
want: opensearch.NewTermQuery[string]("Name").Value("moby di*"),
},
{
name: "remaps known field names",
@@ -31,12 +28,18 @@ func TestKQL_Compile(t *testing.T) {
&ast.StringNode{Key: "mediatype", Value: "application/gzip"},
},
},
want: opensearch.NewBoolQuery().
Must(
opensearch.NewTermQuery[string]("MimeType").Value("application/gzip"),
),
want: opensearch.NewTermQuery[string]("MimeType").Value("application/gzip"),
},
// kql to os dsl - type tests
{
name: "remaps known field names",
got: &ast.Ast{
Nodes: []ast.Node{
&ast.StringNode{Key: "a", Value: "a"},
},
},
want: opensearch.NewTermQuery[string]("a").Value("a"),
},
// kql to os dsl - structure tests
{
name: "[*]",
@@ -45,10 +48,7 @@ func TestKQL_Compile(t *testing.T) {
&ast.StringNode{Key: "name", Value: "moby di*"},
},
},
want: opensearch.NewBoolQuery().
Must(
opensearch.NewTermQuery[string]("Name").Value("moby di*"),
),
want: opensearch.NewTermQuery[string]("Name").Value("moby di*"),
},
{
name: "[* *]",