enhancement(search): implement kql NOT operator to os dsl bool-query MUST_NOT

This commit is contained in:
fschade
2025-08-03 13:57:57 +02:00
parent 3401f49a8c
commit d97b2a6410
2 changed files with 62 additions and 1 deletions

View File

@@ -47,12 +47,15 @@ func (k *KQL) compile(nodes []ast.Node) (Builder, error) {
for i, node := range nodes {
nextOp := k.getOperatorValueAt(nodes, i+1)
prevOp := k.getOperatorValueAt(nodes, i-1)
switch {
case nextOp == kql.BoolOR:
add = boolQuery.Should
case nextOp == kql.BoolAND:
add = boolQuery.Must
case prevOp == kql.BoolNOT:
add = boolQuery.MustNot
}
builder, err := k.getBuilder(node)

View File

@@ -210,6 +210,36 @@ func TestKQL_Compile(t *testing.T) {
opensearch.NewTermQuery[string]("age").Value("32"),
),
},
{
Name: "[NOT *]",
Got: &ast.Ast{
Nodes: []ast.Node{
&ast.OperatorNode{Value: "NOT"},
&ast.StringNode{Key: "age", Value: "32"},
},
},
Want: opensearch.NewBoolQuery().
MustNot(
opensearch.NewTermQuery[string]("age").Value("32"),
),
},
{
Name: "[* NOT *]",
Got: &ast.Ast{
Nodes: []ast.Node{
&ast.StringNode{Key: "name", Value: "openCloud"},
&ast.OperatorNode{Value: "NOT"},
&ast.StringNode{Key: "age", Value: "32"},
},
},
Want: opensearch.NewBoolQuery().
Must(
opensearch.NewTermQuery[string]("Name").Value("openCloud"),
).
MustNot(
opensearch.NewTermQuery[string]("age").Value("32"),
),
},
{
Name: "[* OR * OR *]",
Got: &ast.Ast{
@@ -269,7 +299,7 @@ func TestKQL_Compile(t *testing.T) {
),
},
{
Name: "NEW[* OR * AND *]",
Name: "[* OR * AND *]",
Got: &ast.Ast{
Nodes: []ast.Node{
&ast.StringNode{Key: "a", Value: "a"},
@@ -314,6 +344,34 @@ func TestKQL_Compile(t *testing.T) {
opensearch.NewTermQuery[string]("d").Value("d"),
),
},
{
Name: "[[* OR * OR *] AND NOT *]",
Got: &ast.Ast{
Nodes: []ast.Node{
&ast.GroupNode{Nodes: []ast.Node{
&ast.StringNode{Key: "a", Value: "a"},
&ast.OperatorNode{Value: "OR"},
&ast.StringNode{Key: "b", Value: "b"},
&ast.OperatorNode{Value: "OR"},
&ast.StringNode{Key: "c", Value: "c"},
}},
&ast.OperatorNode{Value: "AND"},
&ast.OperatorNode{Value: "NOT"},
&ast.StringNode{Key: "d", Value: "d"},
},
},
Want: opensearch.NewBoolQuery().
Must(
opensearch.NewBoolQuery(opensearch.BoolQueryOptions{MinimumShouldMatch: 1}).
Should(
opensearch.NewTermQuery[string]("a").Value("a"),
opensearch.NewTermQuery[string]("b").Value("b"),
opensearch.NewTermQuery[string]("c").Value("c"),
),
).MustNot(
opensearch.NewTermQuery[string]("d").Value("d"),
),
},
}
for _, test := range tests {