Skip to content

Repository files navigation

Hex.pm Version Hex docs License

KQL

You're reading the main branch's readme. Please visit hexdocs for the latest published documentation.

Parser for a simplified version of the Kibana query language into an AST.

What is supported?

  • Comparison operators: >, >=, <, <=, :
  • Quoted and unquoted values, including escape characters: make:"foo bar", make:foo\ bar
  • Not, and, & or operators: NOT make:foo, make:foo AND model:bar, make:foo OR model:bar
  • Grouping expressions with (): make:foo OR (make:bar AND model:bar)
  • UTF-8 values: make:苹果
  • Glob values: make:foo*
  • Value lists: make: (foo OR bar), make: [foo, bar]
  • Nested fields, dotted or braced: first.second: foo and first: { second: foo and third: bar } both produce a nested node per path segment, wrapping the expression at the leaf
  • Quoted field names: "first.second": foo is a literal field name — quoting makes the dots characters rather than path separators

What is missing?

  • Matching multiple fields (glob values in field name): make*:foo

Installation

def deps do
  [
    {:kql, "~> 0.2.0"}
  ]
end

Examples

iex> KQL.parse("make:foo")
{:ok, %{
  "ast" => %{
    "field" => "make",
    "operator" => "=",
    "type" => "comparison",
    "value" => %{
      "type" => "value",
      "term" => "foo",
      "glob" => false,
      "quoted" => false
    }
  },
  "meta" => %{
    "original_query" => "make:foo",
    "version" => "0.2.0"
  }
}}

Globs are supported too:

iex> KQL.parse("make:A* AND model:*X")
{:ok, %{
  "ast" => %{
    "type" => "and",
    "terms" => [%{
      "type" => "comparison",
      "field" => "make",
      "operator" => "=",
      "value" => %{
        "type" => "value",
        "term" => "A*",
        "glob" => true,
        "quoted" => false
      }
    },
    %{
      "type" => "comparison",
      "field" => "model",
      "operator" => "=",
      "value" => %{
        "type" => "value",
        "term" => "*X",
        "glob" => true,
        "quoted" => false
      }
    }]
  },
  "meta" => %{
    "original_query" => "make:A* AND model:*X",
    "version" => "0.2.0"
  }
}}

A dotted field name is a path, producing one nested node per dot with the comparison at the leaf:

iex> KQL.parse("car.make:alfa")
{:ok, %{
  "ast" => %{
    "type" => "nested",
    "path" => "car",
    "term" => %{
      "type" => "comparison",
      "field" => "make",
      "operator" => "=",
      "value" => %{
        "type" => "value",
        "term" => "alfa",
        "glob" => false,
        "quoted" => false
      }
    }
  },
  "meta" => %{
    "original_query" => "car.make:alfa",
    "version" => "0.2.0"
  }
}}

The braced form wraps a whole expression instead of a single comparison, so car:{make:alfa} and car.make:alfa produce the same AST:

iex> KQL.parse("car:{make:alfa AND year>=2020}")
{:ok, %{
  "ast" => %{
    "type" => "nested",
    "path" => "car",
    "term" => %{
      "type" => "and",
      "terms" => [%{
        "type" => "comparison",
        "field" => "make",
        "operator" => "=",
        "value" => %{
          "type" => "value",
          "term" => "alfa",
          "glob" => false,
          "quoted" => false
        }
      },
      %{
        "type" => "comparison",
        "field" => "year",
        "operator" => ">=",
        "value" => %{
          "type" => "value",
          "term" => "2020",
          "glob" => false,
          "quoted" => false
        }
      }]
    }
  },
  "meta" => %{
    "original_query" => "car:{make:alfa AND year>=2020}",
    "version" => "0.2.0"
  }
}}

Quoting a field name makes it literal, so its dots are characters rather than path separators and the result stays a plain comparison:

iex> KQL.parse(~S|"car.make":alfa|)
{:ok, %{
  "ast" => %{
    "type" => "comparison",
    "field" => "car.make",
    "operator" => "=",
    "value" => %{
      "type" => "value",
      "term" => "alfa",
      "glob" => false,
      "quoted" => false
    }
  },
  "meta" => %{
    "original_query" => "\"car.make\":alfa",
    "version" => "0.2.0"
  }
}}

About

Kibana Query Language parser in Elixir

Resources

Stars

3 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages