158 lines
5.4 KiB
Python
158 lines
5.4 KiB
Python
# Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
# or more contributor license agreements. Licensed under the Elastic License
|
|
# 2.0; you may not use this file except in compliance with the Elastic License
|
|
# 2.0.
|
|
|
|
import unittest
|
|
import kql
|
|
|
|
|
|
class TestKQLtoDSL(unittest.TestCase):
|
|
def validate(self, kql_source, dsl, **kwargs):
|
|
actual_dsl = kql.to_dsl(kql_source, **kwargs)
|
|
self.assertListEqual(list(actual_dsl), ["bool"])
|
|
self.assertDictEqual(actual_dsl["bool"], dsl)
|
|
|
|
def test_field_match(self):
|
|
def match(**kv):
|
|
return {"filter": [{"match": kv}]}
|
|
|
|
self.validate("user:bob", match(user="bob"))
|
|
self.validate("number:-1", match(number=-1))
|
|
self.validate("number:1.1", match(number=1.1))
|
|
self.validate("boolean:true", match(boolean=True))
|
|
self.validate("boolean:false", match(boolean=False))
|
|
|
|
def test_field_exists(self):
|
|
self.validate("user:*", {"filter": [{"exists": {"field": "user"}}]})
|
|
|
|
def test_field_inequality(self):
|
|
def rng(op, val):
|
|
return {"filter": [{"range": {"field": {op: val}}}]}
|
|
|
|
self.validate("field < value", rng("lt", "value"))
|
|
self.validate("field > -1", rng("gt", -1))
|
|
self.validate("field <= 1.1", rng("lte", 1.1))
|
|
self.validate("field >= 0", rng("gte", 0))
|
|
self.validate("field >= abc", rng("gte", "abc"))
|
|
|
|
def test_or_query(self):
|
|
self.validate(
|
|
"field:value or field2:value2",
|
|
{"should": [{"match": {"field": "value"}}, {"match": {"field2": "value2"}}], "minimum_should_match": 1},
|
|
)
|
|
|
|
def test_and_query(self):
|
|
self.validate(
|
|
"field:value and field2:value2",
|
|
{"filter": [{"match": {"field": "value"}}, {"match": {"field2": "value2"}}]},
|
|
)
|
|
|
|
def test_not_query(self):
|
|
self.validate("not field:value", {"must_not": [{"match": {"field": "value"}}]})
|
|
self.validate("field:(not value)", {"must_not": [{"match": {"field": "value"}}]})
|
|
self.validate("field:(a and not b)", {
|
|
"filter": [{"match": {"field": "a"}}],
|
|
"must_not": [{"match": {"field": "b"}}]
|
|
})
|
|
self.validate(
|
|
"not field:value and not field2:value2",
|
|
{"must_not": [{"match": {"field": "value"}}, {"match": {"field2": "value2"}}]},
|
|
)
|
|
self.validate(
|
|
"not (field:value or field2:value2)",
|
|
{
|
|
"must_not": [
|
|
{
|
|
"bool": {
|
|
"minimum_should_match": 1,
|
|
"should": [{"match": {"field": "value"}}, {"match": {"field2": "value2"}}],
|
|
}
|
|
}
|
|
]
|
|
},
|
|
optimize=False,
|
|
)
|
|
|
|
self.validate("not (field:value and field2:value2)",
|
|
{
|
|
"must_not": [
|
|
{"match": {"field": "value"}},
|
|
{"match": {"field2": "value2"}}
|
|
]
|
|
})
|
|
|
|
def test_optimizations(self):
|
|
self.validate(
|
|
"(field:value or field2:value2) and field3:value3",
|
|
{
|
|
"should": [{"match": {"field": "value"}}, {"match": {"field2": "value2"}}],
|
|
"filter": [{"match": {"field3": "value3"}}],
|
|
"minimum_should_match": 1,
|
|
},
|
|
)
|
|
|
|
self.validate(
|
|
"(field:value and field2:value2) or field3:value3",
|
|
{
|
|
"should": [
|
|
{"bool": {"filter": [{"match": {"field": "value"}}, {"match": {"field2": "value2"}}]}},
|
|
{"match": {"field3": "value3"}},
|
|
],
|
|
"minimum_should_match": 1,
|
|
},
|
|
)
|
|
|
|
self.validate(
|
|
"a:(v1 or v2 or v3) or b:(v4 or v5)",
|
|
{
|
|
"should": [
|
|
{"match": {"a": "v1"}},
|
|
{"match": {"a": "v2"}},
|
|
{"match": {"a": "v3"}},
|
|
{"match": {"b": "v4"}},
|
|
{"match": {"b": "v5"}},
|
|
],
|
|
"minimum_should_match": 1,
|
|
},
|
|
)
|
|
|
|
self.validate(
|
|
"a:(v1 or v2 or v3) and b:(v4 or v5)",
|
|
{
|
|
"should": [
|
|
{"match": {"a": "v1"}},
|
|
{"match": {"a": "v2"}},
|
|
{"match": {"a": "v3"}}
|
|
],
|
|
"filter": [
|
|
{
|
|
"bool": {
|
|
"should": [
|
|
{"match": {"b": "v4"}},
|
|
{"match": {"b": "v5"}}
|
|
],
|
|
"minimum_should_match": 1
|
|
}
|
|
}
|
|
],
|
|
"minimum_should_match": 1,
|
|
},
|
|
)
|
|
|
|
self.validate(
|
|
"(field:value and not field2:value2) or field3:value3",
|
|
{
|
|
"should": [
|
|
{
|
|
"bool": {
|
|
"filter": [{"match": {"field": "value"}}],
|
|
"must_not": [{"match": {"field2": "value2"}}],
|
|
}
|
|
},
|
|
{"match": {"field3": "value3"}},
|
|
],
|
|
"minimum_should_match": 1,
|
|
},
|
|
)
|