diff --git a/pkg/queryexpr/es_expr.go b/pkg/queryexpr/es_expr.go index 40b743ef..70c36b0d 100644 --- a/pkg/queryexpr/es_expr.go +++ b/pkg/queryexpr/es_expr.go @@ -107,6 +107,9 @@ func (e ESExpr) binaryNodeToEsQuery(n *ast.BinaryNode) (interface{}, error) { // case "==": if leftStr, ok := left.(string); ok { + if right == nil { + return e.mustNotExistQuery(leftStr), nil + } return e.termQuery(leftStr, right), nil } result, err := getQueryExprResult(n.String()) @@ -117,6 +120,9 @@ func (e ESExpr) binaryNodeToEsQuery(n *ast.BinaryNode) (interface{}, error) { // case "!=": if leftStr, ok := left.(string); ok { + if right == nil { + return e.mustExistQuery(leftStr), nil + } return e.mustNotQuery(leftStr, right), nil } result, err := getQueryExprResult(n.String()) @@ -257,6 +263,30 @@ func (ESExpr) mustNotQuery(field string, value interface{}) map[string]interface } } +func (ESExpr) mustExistQuery(field string) map[string]interface{} { + return map[string]interface{}{ + "bool": map[string]interface{}{ + "must": map[string]interface{}{ + "exists": map[string]interface{}{ + "field": field, + }, + }, + }, + } +} + +func (ESExpr) mustNotExistQuery(field string) map[string]interface{} { + return map[string]interface{}{ + "bool": map[string]interface{}{ + "must_not": map[string]interface{}{ + "exists": map[string]interface{}{ + "field": field, + }, + }, + }, + } +} + func (ESExpr) rangeQuery(field, operator string, value interface{}) map[string]interface{} { return map[string]interface{}{ "range": map[string]interface{}{ diff --git a/pkg/queryexpr/es_expr_test.go b/pkg/queryexpr/es_expr_test.go index c66b98c9..b3e2d8e6 100644 --- a/pkg/queryexpr/es_expr_test.go +++ b/pkg/queryexpr/es_expr_test.go @@ -50,6 +50,24 @@ func TestESExpr_ToQuery(t *testing.T) { want: `{"query":{"range":{"updated_at":{"gt":"2024-04-05 23:59:59"}}}}`, wantErr: false, }, + { + name: "equals to nil", + expr: queryexpr.ESExpr(`refreshed_at == nil`), + want: `{"query":{"bool":{"must_not":{"exists":{"field":"refreshed_at"}}}}}`, + wantErr: false, + }, + { + name: "not equals to nil", + expr: queryexpr.ESExpr(`refreshed_at != nil`), + want: `{"query":{"bool":{"must":{"exists":{"field":"refreshed_at"}}}}}`, + wantErr: false, + }, + { + name: "equals to nil and not equal to nil", + expr: queryexpr.ESExpr(`refreshed_at == nil && updated_at != nil`), + want: `{"query":{"bool":{"must":[{"bool":{"must_not":{"exists":{"field":"refreshed_at"}}}},{"bool":{"must":{"exists":{"field":"updated_at"}}}}]}}}`, + wantErr: false, + }, { name: "in condition", expr: queryexpr.ESExpr(`service in ["test1","test2","test3"]`),