Skip to main content

Elasticsearch API

Elasticsearch client api used across multiple services, handles retries and exponential backoff

Installation​

# Using pnpm
pnpm add @terascope/elasticsearch-api
# Using npm
npm install --save @terascope/elasticsearch-api

Usage​

const { Client } = require('elasticsearch');
const elasticsearchAPI = require('@terascope/elasticsearch-api');
const bunyan = require('bunyan');

const logger = bunyan.createLogger({ name: 'someName' });
const client = new Client({ host: ["127.0.0.1:9200"] });
const opConfig = { full_response: false };

const elasticsearch = elasticsearchAPI(client, logger, opConfig);

const query = elasticsearch.buildQuery(opConfig, msg);
const results = await elasticsearch.search(query);
console.log(results);

Configuration​

The @terascope/elasticsearch-api module must be passed in an opensearch client and a bunyan based logger. You may also optional pass in an object as the third argument.

ConfigurationDescriptionTypeNotes
full_responseIf using the search method, set this to true will return all metadata for the requestBooleanoptional, defaults to retuning data without its metadata attached
indexonly used if you are using the version methodStringrequired if using the version method, if not then its optional

API Methods​

The majority of methods exhibit the same behavior of the native elasticsearch client

get​

It gets a single document

Query requires:

  • id
  • type
  • index
const query = {id: 'someID', type: 'someType', index: 'someIndex'};

elasticsearch.get(query)
.then(function(results){
console.log(results)
})

index​

This will index a document to a given index

Query requires:

  • index
  • type
  • body
const query = {index: 'someIndex', type: 'someType', body: {actual: 'data'};

elasticsearch.index(query)
.then(function(results){
console.log(results)
});

indexWithId​

This will index a document to a given index with a specific id

Query requires:

  • index
  • type
  • id
  • body
const query = {
index: 'someIndex',
type: 'someType',
id: 'someID',
body: {actual: 'data'}
};

elasticsearch.indexWithId(query)
.then(function(results){
console.log(results)
})

create​

Please reference index, they do the same except create will throw if doc already exists

update​

Update parts of a document, body is a partial document, which will be merged with the existing one

Query requires:

  • index
  • type
  • id
  • body
const query = {
index: 'someIndex',
type: 'someType',
id: 'someId',
body: {
doc: {
partial: 'document'
}
}
};

elasticsearch.update(query)
.then(function(results){
console.log(results)
})

remove​

Deletes a document for a given id

Query requires:

  • index
  • type
  • id
const query = {index: 'someIndex', type: 'someType', id: 'someId'};

elasticsearch.remove(query)
.then(function(results){
console.log(results)
})

Searches elasticsearch

Query requires:

  • index (can be a single index or multiple)

optional:

  • q (lucene query)
  • body (Elasticsearch’s Query DSL)
const query = {index: 'someIndex', q: 'some:Data NOT other:Data'};
const query2 = {
"index": "mapping_test",
"size": 2000,
"q": "bytes:>80000",
"body": {
"query": {
"range": {
"created": {
"gte": "2016-11-28T11:18:07.018-07:00",
"lt": "2016-11-28T11:18:07.031-07:00"
}
}
}
}
};

elasticsearch.search(query)
.then(function(results){
console.log(results)
})

Note​

  • If the incoming query has size set to 0, then it will return the count of the given query
  • If the passed in opConfig (third argument on instantiation of api) has set full_response to true, it will return docs with their associated metadata

version​

Verifies if a given index exists and logs what the max_result_window for said index

Query requires:

  • index (requires passed in opConfig to have set an index key with the value set to a index)
const opConfig = {index: 'someIndex'}
const elasticsearch = require('@terascope/elasticsearch-api')(client, logger, opConfig);

elasticsearch.version()
.then(function(){
// do stuff
})
.catch(function(err){
//index does not exist or some other error
})

putTemplate​

Adds a template

Query requires:

  • template
  • name
const client = getClient(context, context.sysconfig.teraslice.state, 'elasticsearch');
const template = require('./backends/mappings/logs.json');
const name = 'logs_template';

elasticsearch.putTemplate(template, name)

bulkSend​

Uses the client bulk functionality with exponential back-off retries

Query requires:

  • data (formatted to work with opensearch bulk queries)
const elasticsearch = require('@terascope/elasticsearch-api')(client, logger, opConfig);
elasticsearch.bulkSend([
{
action: {
index: { _index: 'some_index', _id: 1 }
},
data: { title: 'foo' }
},
{
action: {
delete: { _index: 'some_index', _id: 5 }
}
}
])
.then(() => {
//all done sending data
});

nodeInfo​

directly calls opensearch client.nodes.info()

nodeStats​

directly calls opensearch client.nodes.stats()

index_exists​

calls client.indices.exists() with and retries if queue is overloaded

Query requires:

  • index
const existQuery = {index: index_name};
elasticsearch.index_exists(existQuery)

index_create​

calls client.indices.create() with and retries if queue is overloaded

Query requires:

  • index
  • body (mapping for index)
const createQuery = {index: index_name, body: mapping};
elasticsearch.index_create(createQuery)

index_refresh​

calls client.indices.refreash() with and retries if queue is overloaded

Query requires:

  • index
const query = {index: index_name};
elasticsearch.index_refresh(query)

index_recovery​

calls client.indices.recovery() with and retries if queue is overloaded

Query requires:

  • index
const existQuery = {index: index_name};
elasticsearch.index_recovery(existQuery)

buildQuery​

basic elasticsearch dsl query builder

Query requires:

  • opConfig (object)
  • msg (object)

Basic usage

const elasticsearch = require('@terascope/elasticsearch-api')(client, logger, opConfig);
const query = elasticsearch.buildQuery(opConfig, msg);
elasticsearch.search(query)

Configuration for opConfig​

ConfigurationDescriptionTypeNotes
indexIndex in which you will read fromStringrequired
fieldsDetermines what fields are sent back in the returning query. Setting it to true or false will determine if the _source field should be returned. Setting it to a list of fields will return results only of those fields and if set to a single string will only return that specific fieldString, Array of Strings, Booleanoptional
date_field_namethe field name of the document on which you will be performing a range queryStringrequired only if msg parameter has a start and end value,
queryMust be lucene query syntax. If set then this will add a lucene query to the final queryStringoptional

Configuration for msg​

ConfigurationDescriptionTypeNotes
countdetermines the size parameter of the queryNumberrequired
startused for a range query, searches for greater than or equal to this valueString (date)optional, must be used in conjunction with end
endused for a range query, searches for less than this value, non-inclusiveString (date)optional, must be used in conjunction with start
keyif set then this will perform a wildcard query using this value against all document's _id valueStringoptional

Example of query generated:

In the following example, this will create a query searching the index: someIndex with a _id that matches a76f*, with bytes greater than 80000 and in-between two dates
const opConfig = {
date_field_name: 'created',
index: 'someIndex',
query: 'bytes:>80000'
};

const msg = {
count: 2000,
start: "2016-11-28T11:18:07.018-07:00",
end: "2016-11-28T11:18:07.031-07:00",
key: "a76f*"
};

const query = elasticsearch.buildQuery(opConfig, msg);
console.log(query);

const obj = {
"index": "someIndex",
"size": 2000,
"body": {
"query": {
bool: {
must: [
{
"range": {
"created": {
"gte": "2016-11-28T11:18:07.018-07:00",
"lt": "2016-11-28T11:18:07.031-07:00"
}
}
},
{
query_string: {
query: "bytes:>80000"
}
},
{
wildcard: {
_uid: "a76f*"
}
}

]
}
}
}
};