elasticsearch-helper
A nodejs module to do elasticsearch queries easily
disclaimer
I experienced a lot of issues in the past due to the way Elasticsearch handles the queries. I decided to create helper that we currently use on production level at https://headhunterportal.com and some other projects and so far it had helped us to drastically reduce the complexity of readability of our code.
With this helper you will be able to query your elasticsearch clusters very easily. Everything is chainable and the query always returns a promise.
NOTE: Even if we use this on production level still find bugs and add improvements to the module codebase. Feel free to for it and modify it for your own needs.
installation
npm install --save elasticsearch-helper
usage
add client
let esH = require("elasticsearch-helper")
esH.AddClient("127.0.0.1:9200");
esH.AddClient("client1","127.0.0.1:9200");
esH.AddClient("client1","127.0.0.1:9200",true);
use client
The client is chainable which means that you can call functions one after the other until you execute the query. The query is then returning a promise.
Initialise a query:
const esH = require("elasticsearch-helper")
esH.query("Index1");
esH.query("Index*");
esH.query("Index1","Type1");
esH.query("Index1","Type1)".use("Client1")
Doing query:
For those example we will use the query variable 'q':
var q = esH.query("Index1","Type1");
Single Document
Retrieve
q.id("ID")
q.run()
.then(function(hit){
console.log(hit.id())
console.log(hit.index())
console.log(hit.type())
console.log(hit.data())
})
Delete
q.id("ID")
q.delete()
.then(function(hit){
})
Create/Overwrite
q.id("ID")
q.body({...})
q.run()
.then(function(hit){
})
Update
q.id("ID")
q.update({...})
q.run()
.then(function(hit){
})
Multiple Documents
Types & search options
This helper includes the different search features of Elasticsearch such as must
, must_not
etc.
GETs and DELETEs are using the same methodology for querying building. Example:
q.must(
esH.type.term("fieldname","fieldvalue"),
esH.type.terms("fieldname","fieldvalues"),
esH.type.exists("fieldname"),
esH.type.range({
gte:1,
lte:10
}),
esH.filter.should(
esH.type.terms("fieldname2","fieldvalues")
)
)
q.must_not(
)
q.should(
)
q.filter(
)
Retrieve
q.must(
).run().then(function(hits){
var hit = hits[0];
console.log(hit.id())
console.log(hit.index())
console.log(hit.type())
console.log(hit.data())
})
Delete
Delete by query is only avalaible on Elasticsearch 5.X
q.must(
).delete().then(function(hits){
})
aggregations // BETA
Elasticsearch has a very powerful aggregation system but the way to handle it can be tricky. I tried to solve this issue by wrapping it in what I think is the simplest way.
NOTE: Right now I only handle 2 types of aggregation, terms
and date_histogram
q.aggs(
ES.agg.date_histogram("created_date")("date_created","1d")
.aggs(
ES.agg.terms("first_name")("data.first_name")
)
).run()
.then(function(response){
var arrayAggList = response.agg("created_date")
var arrayValues = arrayAggList.values()
var firstValue = arrayValues[0];
var valueID = firstValue.id();
var valueData = firstValue.data();
var arrayChildAggList = arrayAggList.agg("first_name");
for(var parentKeyvalue in arrayChildAggList){
arrayChildAggList[parentKeyvalue].values().forEach(function(value){
console.log(parentKeyvalue, value.id(),value.data());
})
}
})
Other options
q.size(1000)
q.fields("name","id")
Examples
Query
let esH = require("elasticsearch-helper")
esH.AddClient("client1","127.0.0.1:9200");
esH.query("Index1","Type1")
.use("client1")
.size(10)
.must(
esH.addType().term("name","John"),
esH.addType().terms("lastname",["Smith","Wake"])
)
.must_not(
esH.addType().range("age",{
lte:20,
gte:30
})
)
.run()
.then(function(hits){
})
Query with aggregation
let esH = require("elasticsearch-helper")
esH.AddClient("client1","127.0.0.1:9200");
esH.Query("user")
.size(1001)
.must(
esH.type.term("name","jacques"),
esH.type.range("age",{gt:20,lte:40}),
esH.filter.should(
esH.type.term("color","blue"),
esH.type.term("vehicle","car")
)
)
.aggs(
esH.agg.date_histogram("created_date")("date_created","1d")
.aggs(
esH.agg.terms("first_name")("data.first_name.raw")
)
)
.run()
.then(function(response){
var arrayAggList = response.agg("created_date")
var arrayValues = arrayAggList.values()
var firstValue = arrayValues[0];
var valueID = firstValue.id();
var valueData = firstValue.data();
var arrayChildAggList = arrayAggList.agg("first_name");
for(var parentKeyvalue in arrayChildAggList){
arrayChildAggList[parentKeyvalue].values().forEach(function(value){
console.log(parentKeyvalue, value.id(),value.data());
})
}
}).catch(function(err){
console.log(err)
})