A lightweight query builder for Elastic Search and OpenSearch. You can convert a simple JSON Rule built with the popular JSON Rule Engine library and turn into a valid Elastic Search query.
Supports
- And / OR conditions
- Nested conditions
- Offsets / pagination
- Basic Aggregations
- Custom operators
- Custom Aggregators
- and more
Inspired By: json-rules-engine elastic-builder
use toJson function to convert the query to the json
import QueryBuilder from 'elastic-graph'
// Initialize the class
const queryBuilder = new QueryBuilder()
// Usage
queryBuilder.setRule({
all: [
{
any: [
{fact: 'field-1', operator: 'equal', value: 'value-1'},
{fact: 'field-2', operator: 'notEqual', value: 'value-2'},
],
},
{
all: [
{
fact: 'field-3', operator: 'lessThanRelative', value: '3', additionalProperties: {
format: 'X', // format uses the luxon time formate
},
},
],
},
],
}).toJson()
import QueryBuilder from "elastic-graph";
const queryBuilder = new QueryBuilder();
queryBuilder.addOperator(
"newOperator",
(fact: string, value: any, additionalProperties: DynamicObject) => {
return elasticBuilder.matchQuery(fact, value);
}
);
queryBuilder.addOperator(
"newOperator",
(fact: string, value: any, additionalProperties: DynamicObject) => {
return elasticBuilder.matchQuery(fact, value);
}
);
queryBuilder.removeOperator("newOperator");
queryBuilder.addAggregator(
"newAggregator",
(name: string, fieldName: any, additionalProperties: DynamicObject) => {
return elasticBuilder.sumAggregation(name, fieldName);
}
);
queryBuilder.addAggregator(
"newAggregator",
(name: string, fieldName: any, additionalProperties: DynamicObject) => {
return elasticBuilder.sumAggregation(name, fieldName);
}
);
queryBuilder.removeAggregator("newAggregator");
- setRouting set the query routing value
queryBuilder.setRoutingValue("user1");
queryBuilder.setRule({
all: [{ fact: "field", operator: "equal", value: "value" }],
});
- skips the give value of records from the query result
queryBuilder.offset(10);
- gets the given number of records
queryBuilder.limit(10);
- convert the query to json
queryBuilder.setRoutingValue("user1").offset(10).limit(10)setRule({
all: [{ fact: "field", operator: "equal", value: "value" }],
}).toJson();
queryBuilder.setAggregator([
{ name: "aggregator1", aggregator: "sum", fieldName: "field-1" },
]);
queryBuilder.sum("aggregator-sum", "field-2");
// or
queryBuilder.sum([{ name: "aggregator-sum", fieldName: "field-2" }]);
queryBuilder.avg("aggregator-avg", "field-2");
// or
queryBuilder.avg([{ name: "aggregator-avg", fieldName: "field-2" }]);
queryBuilder.max("aggregator-max", "field-2");
// or
queryBuilder.max([{ name: "aggregator-max", fieldName: "field-2" }]);
queryBuilder.min("aggregator-min", "field-2");
// or
queryBuilder.min([{ name: "aggregator-min", fieldName: "field-2" }]);
queryBuilder.sort("field-2", "desc").sort("field-3", "desc");
// or
queryBuilder.sort([
{ name: "field-2", order: "desc" },
{ name: "field-3", order: "desc" },
]);
- json structure
{
"fact": "field-name",
"operator": "operator Identifier",
"value": "value",
"additionalProperties": {
// Additional properties for the query
}
}
setRule
queryBuilder.setRule({
all:[
{{
"fact":"field-name",
"operator":"operator Identifier",
"value":"value",
"additionalProperties":{
// Additional properties for the query
}
}}
]
})
-
setAggregator json format
{ "name": "aggregator name", "aggregator": "aggregator identifier", "fieldName": "name of the field aggregation to be performed", "additionalProperties":{ // Additional Properties for the aggregator } }
-
sample Rule object
equal uses term query
{ "fact": "fieldName", "operator": "equal", "value": "value" }
-
sample Rule object
containsString uses match query
{ "fact": "fieldName", "operator": "containsString", "value": "value" }
-
sample Rule object
in value give the null replacement value given in the search Database blank uses term query
{ "fact": "fieldName", "operator": "equal", "value": "value" }
-
sample Rule object
notEqual uses term query
{ "fact": "fieldName", "operator": "notEqual", "value": "value" }
-
sample Rule object
notContainsString uses match query
{ "fact": "fieldName", "operator": "notContainsString", "value": "value" }
-
sample Rule object
check for the field value is not null
{ "fact": "fieldName", "operator": "notBlank", "value": "value" }
-
sample Rule object
greaterThanAbsolute uses the range query
{ "fact": "fieldName", "operator": "greaterThanAbsolute", "value": "value" }
-
sample Rule object
lessThanAbsolute uses the range query
{ "fact": "fieldName", "operator": "lessThanAbsolute", "value": "value" }
-
sample Rule object
greaterThanRelative uses the range query, But there is a preprocessing it convert to the given format(uses luxon time formatting)
{ "fact": "fieldName", "operator": "greaterThanRelative", "value": "value", "additionalProperties": { "format": "yyyy" } }
-
sample Rule object
lessThanRelative uses the range query, But there is a preprocessing it convert to the given format(uses luxon time formatting)
{ "fact": "fieldName", "operator": "lessThanRelative", "value": "value", "additionalProperties": { "format": "yyyy" } }
-
sample Rule object
notEqualRelative uses the range query, But there is a preprocessing it convert to the given format(uses luxon time formatting)
{ "fact": "fieldName", "operator": "notEqualRelative", "value": "value", "additionalProperties": { "format": "yyyy" } }
-
usage sum aggregator is added as native function
//for single sum aggregator queryBuilder.sum("aggregatorName", "fieldName"); // or //for multiple sum aggregator queryBuilder.sum([ { name: "aggregator-1", fieldName: "field-1" }, { name: "aggregator-2", fieldName: "field-2" }, ]);
-
usage max aggregator is added as native function
//for single max aggregator queryBuilder.max("aggregatorName", "fieldName"); // or //for multiple max aggregator queryBuilder.max([ { name: "aggregator-1", fieldName: "field-1" }, { name: "aggregator-2", fieldName: "field-2" }, ]);
-
usage sum aggregator is added as native function
//for single min aggregator queryBuilder.min("aggregatorName", "fieldName"); // or //for multiple min aggregator queryBuilder.min([ { name: "aggregator-1", fieldName: "field-1" }, { name: "aggregator-2", fieldName: "field-2" }, ]);
-
usage avg aggregator is added as native function
//for single avg aggregator queryBuilder.avg("aggregatorName", "fieldName"); // or //for multiple avg aggregator queryBuilder.avg([ { name: "aggregator-1", fieldName: "field-1" }, { name: "aggregator-2", fieldName: "field-2" }, ]);
To add custom operator user addOperator function it take two argument operator initializer and callback (callback must return the instance of elasticBuilder )
elasticBuilder -> elastic-builder see reference
import QueryBuilder, { DynamicObject, elasticBuilder } from "elastic-graph";
const queryBuilder = new QueryBuilder();
queryBuilder.addOperator(
"newOperator",
(fact: string, value: any, additionalProperties: DynamicObject) => {
return elasticBuilder.matchQuery(fact, value);
}
);
queryBuilder
.setRule({
all: [{ fact: "fieldName", operator: "newOperator", value: "test" }],
})
.toJson();
To add custom aggregator use addAggregator function it take two argument aggregator initializer and callback (callback must return the instance of elasticBuilder )
elasticBuilder -> elastic-builder see reference
import QueryBuilder, { DynamicObject, elasticBuilder } from "elastic-graph";
const queryBuilder = new QueryBuilder();
queryBuilder.addAggregator(
"newAggregator",
(name: string, fieldName: any, additionalProperties: DynamicObject) => {
return elasticBuilder.sumAggregation(name, fieldName);
}
);
queryBuilder
.setAggregatorRule([
{
name: "aggregatorName",
aggregator: "newAggregator",
fieldName: "fieldName",
},
])
.toJson();