Skip to content

Latest commit

History

5 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Simple Query Compiler

traviscodecovCodacy Badge

A Java library to compile and parse simple filter queries.

The following query formats can be parsed:

// multiple terms with AND and OR operator
(x > 0 && !(y < 1 || z == 'test')) 
//full text search
"text search" test -example

Default term operators:

==, !=, <, <=, >, >=, text, regex

Logical operators:

AND, OR, XOR, NOR

Build

To build the library from sources:

  1. Clone github repository

    $ git clone https://github.com/nRo/SimpleQueryCompiler.git

  2. Change to the created folder and run mvn install

    $ cd SimpleQueryCompiler

    $ mvn install

  3. Include it by adding the following to your project's pom.xml:

<dependencies>
...
<dependency>
<groupId>de.alexgruen</groupId>
<artifactId>querycompiler</artifactId>
<version>0.3-SNAPSHOT</version>
</dependency>
...
</dependencies>

Usage

This library works by defining by building a QueryCompiler for the desired output type. Building a QueryCompiler requires the definition of Creators for the supported term operators (==, !=, <, <=, ...) and logical operators (AND, OR,...). The Creators are responsible to create the target object, for example SQL queries, elasticsearch queries,...

There are two ways to create a QueryCompiler. For the following examples be specify example ElasticSearchQuery as target class:

publicabstractclassElasticSearchQueryimplementsQuery{
//Every query must create an ElasticSearch QueryBuilderpublicabstractQueryBuildercreate();
...
}

If a QueryCompiler is built, input strings can be parsed with:

QueryCompiler<ElasticSearchQuery> esCompiler = ...
ElasticSearchQueryesQuery = esCompiler.compile("(x > 1 && y < 1)");
Override DefaultCreator

DefaultCreator is an abstract class that contains functions for all standard operations. If such a method is not overridden, an error is thrown if the input query string contains the respective operator.

publicclassElasticSearchQueryCreatorextendsDefaultCreator<ElasticSearchQuery> {
//override eq(field,value) to support == operator in input queries//text search is implemented by overriding the fullSearch(Value value) method@OverridepublicElasticSearchQueryeq(Fieldfield, Valuevalue) {
returnnewElasticSearchQuery() {
@OverridepublicQueryBuildercreate() {
returnQueryBuilders.termQuery(field.toString(), value.getValue());
}
};
}
//override other term operator methods: ne (!=), le(>=), lt(>),...
...
//override and(query....) to support AND concatenation of terms@OverridepublicElasticSearchQueryand(ElasticSearchQuery... queries) {
returnnewElasticSearchQuery() {
@OverridepublicQueryBuildercreate() {
BoolQueryBuilderboolQueryBuilder = boolQuery();
for(ElasticSearchQueryq : queries){
boolQueryBuilder.must(q.create());
}
returnboolQueryBuilder;
}
};
}
//override other logic operator methods: OR, XOR, NOR,...
}

The compiler can then be created using the following Builder methods:

QueryCompiler<ElasticSearchQuery> esCompiler
= QueryCompiler.create(ElasticSearchQuery.class)
.withDefaultCreator(newElasticSearchQueryCreator())
.build();
Define creators using QueryCompilerBuilder
QueryCompiler<ElasticSearchQuery> compiler = QueryCompiler
.create(ElasticSearchQuery.class)
.withTermCreator(
TermOperators.EQ,
(field,value) -> newElasticSearchQuery() {
@OverridepublicStringcreate() {
returnQueryBuilders.termQuery(field.toString(), value.getValue());
}
}
)
.withANDCreator(
(queries) -> newElasticSearchQuery() {
BoolQueryBuilderboolQueryBuilder = boolQuery();
for(ElasticSearchQueryq : queries){
boolQueryBuilder.must(q.create());
}
returnboolQueryBuilder;
}
)
).build()

Custom term operators

Custom term operators can be added to the QueryCompilerBuilder. In this example we add a PHRASE operator that creates an matchPhrase query for elasticsearch. User can than input queries like:;

x PHRASE 'test phrase' || y == 'test'
QueryCompiler<ElasticSearchQuery> compiler = QueryCompiler
.create(ElasticSearchQuery.class)
.withTermCreator(
.withTermCreator(
newTermOperator("PHRASE"),
(f,v) -> newElasticSearchQuery() {
@OverridepublicStringcreate() {
returnQueryBuilders.matchPhraseQuery(field.toString(), value.getValue());
}
}
)
)
)

Print queries

Queries are first compiled to a tree before being converted to the target object. This tree can be printed

QueryTreetree = compiler.compileTree(
"(x > 0 && y < 1 || (u == 2 && (h != 1 || z < 2))) || z == 2");
Stringstr = QueryPrinter.DEFAULT.toString(tree.getRoot());
/** * ──┐ OR ├──┐ AND │ ├── (x > 0) │ └── (y < 1) ├──┐ AND │ ├── (u == 2) │ └──┐ OR │ ├── (h != 1) │ └── (z < 2) └── (z == 2) **///The tree can then be converted to the target objectElasticSearchQueryesQuery = compiler.compile(tree);

About

Simple QueryCompiler Library for Java

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages