enhancement(search): implement kql string to os dsl match-phrase-query

This commit is contained in:
fschade
2025-07-30 20:02:39 +02:00
parent 4d5a5dde4b
commit 2c316ea225
4 changed files with 36 additions and 18 deletions

View File

@@ -1,9 +1,11 @@
package opensearch_test
import (
"fmt"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
searchService "github.com/opencloud-eu/opencloud/protogen/gen/opencloud/services/search/v0"
"github.com/opencloud-eu/opencloud/services/search/pkg/opensearch"
@@ -26,9 +28,11 @@ func TestEngine_Search(t *testing.T) {
assert.NoError(t, err)
t.Run("most simple search", func(t *testing.T) {
resp, err := engine.Search(t.Context(), &searchService.SearchIndexRequest{Query: "\"" + document.Name + "\""})
resp, err := engine.Search(t.Context(), &searchService.SearchIndexRequest{
Query: fmt.Sprintf(`"%s" Content:"%s"`, document.Name, document.Content),
})
assert.NoError(t, err)
assert.Len(t, resp.Matches, 1)
require.Len(t, resp.Matches, 1)
assert.Equal(t, int32(1), resp.TotalMatches)
assert.Equal(t, document.Name, resp.Matches[0].Entity.Name)
})

View File

@@ -1,7 +1,7 @@
{
"ID" : "1$2!3",
"Title" : "dumme title",
"Name" : "dummy",
"Name" : "dummy name",
"Content" : "dummy content",
"Size" : 42,
"Mtime" : "2025-07-24 15:15:01.324093 +0200 CEST m=+0.000056251",

View File

@@ -67,7 +67,12 @@ 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)
switch len(strings.Split(node.Value, " ")) {
case 1:
builder = NewTermQuery[string](k.getFieldName(node.Key)).Value(node.Value)
default:
builder = NewMatchPhraseQuery(k.getFieldName(node.Key)).Query(node.Value)
}
case *ast.GroupNode:
group, err := k.compile(node.Nodes)
if err != nil {

View File

@@ -16,10 +16,10 @@ func TestKQL_Compile(t *testing.T) {
name: "Name is the default field",
got: &ast.Ast{
Nodes: []ast.Node{
&ast.StringNode{Value: "moby di*"},
&ast.StringNode{Value: "openCloud"},
},
},
want: opensearch.NewTermQuery[string]("Name").Value("moby di*"),
want: opensearch.NewTermQuery[string]("Name").Value("openCloud"),
},
{
name: "remaps known field names",
@@ -35,32 +35,41 @@ func TestKQL_Compile(t *testing.T) {
name: "remaps known field names",
got: &ast.Ast{
Nodes: []ast.Node{
&ast.StringNode{Key: "a", Value: "a"},
&ast.StringNode{Key: "Name", Value: "openCloud"},
},
},
want: opensearch.NewTermQuery[string]("a").Value("a"),
want: opensearch.NewTermQuery[string]("Name").Value("openCloud"),
},
{
name: "remaps known field names",
got: &ast.Ast{
Nodes: []ast.Node{
&ast.StringNode{Key: "Name", Value: "open cloud"},
},
},
want: opensearch.NewMatchPhraseQuery("Name").Query("open cloud"),
},
// kql to os dsl - structure tests
{
name: "[*]",
got: &ast.Ast{
Nodes: []ast.Node{
&ast.StringNode{Key: "name", Value: "moby di*"},
&ast.StringNode{Key: "name", Value: "openCloud"},
},
},
want: opensearch.NewTermQuery[string]("Name").Value("moby di*"),
want: opensearch.NewTermQuery[string]("Name").Value("openCloud"),
},
{
name: "[* *]",
got: &ast.Ast{
Nodes: []ast.Node{
&ast.StringNode{Key: "name", Value: "moby di*"},
&ast.StringNode{Key: "name", Value: "openCloud"},
&ast.StringNode{Key: "age", Value: "32"},
},
},
want: opensearch.NewBoolQuery().
Must(
opensearch.NewTermQuery[string]("Name").Value("moby di*"),
opensearch.NewTermQuery[string]("Name").Value("openCloud"),
opensearch.NewTermQuery[string]("age").Value("32"),
),
},
@@ -68,14 +77,14 @@ func TestKQL_Compile(t *testing.T) {
name: "[* AND *]",
got: &ast.Ast{
Nodes: []ast.Node{
&ast.StringNode{Key: "name", Value: "moby di*"},
&ast.StringNode{Key: "name", Value: "openCloud"},
&ast.OperatorNode{Value: "AND"},
&ast.StringNode{Key: "age", Value: "32"},
},
},
want: opensearch.NewBoolQuery().
Must(
opensearch.NewTermQuery[string]("Name").Value("moby di*"),
opensearch.NewTermQuery[string]("Name").Value("openCloud"),
opensearch.NewTermQuery[string]("age").Value("32"),
),
},
@@ -83,14 +92,14 @@ func TestKQL_Compile(t *testing.T) {
name: "[* OR *]",
got: &ast.Ast{
Nodes: []ast.Node{
&ast.StringNode{Key: "name", Value: "moby di*"},
&ast.StringNode{Key: "name", Value: "openCloud"},
&ast.OperatorNode{Value: "OR"},
&ast.StringNode{Key: "age", Value: "32"},
},
},
want: opensearch.NewBoolQuery().
Should(
opensearch.NewTermQuery[string]("Name").Value("moby di*"),
opensearch.NewTermQuery[string]("Name").Value("openCloud"),
opensearch.NewTermQuery[string]("age").Value("32"),
),
},
@@ -98,7 +107,7 @@ func TestKQL_Compile(t *testing.T) {
name: "[* OR * OR *]",
got: &ast.Ast{
Nodes: []ast.Node{
&ast.StringNode{Key: "name", Value: "moby di*"},
&ast.StringNode{Key: "name", Value: "openCloud"},
&ast.OperatorNode{Value: "OR"},
&ast.StringNode{Key: "age", Value: "32"},
&ast.OperatorNode{Value: "OR"},
@@ -107,7 +116,7 @@ func TestKQL_Compile(t *testing.T) {
},
want: opensearch.NewBoolQuery().
Should(
opensearch.NewTermQuery[string]("Name").Value("moby di*"),
opensearch.NewTermQuery[string]("Name").Value("openCloud"),
opensearch.NewTermQuery[string]("age").Value("32"),
opensearch.NewTermQuery[string]("age").Value("44"),
),