UNPKG

es-builder

Version:

Elasticsearch query builder for Node.js

273 lines (212 loc) 7.03 kB
# Elasticsearch Query Builder [![Build Status](https://travis-ci.org/antonvs2/es-builder.svg?branch=master)](https://travis-ci.org/antonvs2/es-builder) Elasticsearch query builder for Node.js, build compatible queries with the Elasticsearch 2.x DSL. Because creating complex queries using the Query DSL is a pain. It just builds the `query` element within the search request body, the complex part. This means that fields like `size` or `from` must be added separately, as well as the likes of `sort`. [Info about Search parameters.](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-body.html#_parameters_4) # Installation The package can be installed as a local module, to be required in your code. ```js npm install es-builder ``` Also, it can be installed globally, ready to be used through the Node.js REPL. ```js npm install -g es-builder ``` # Features - No production dependencies - Can be required as a module or used in the command line - Chainable methods - `built` getter method returns a copy of the object so it can be safely passed to foreign code # Usage ## Used as a local module It is compatible with the [Elasticsearch official client library](https://github.com/elastic/elasticsearch-js): ```js const eb = require('es-builder'); var elasticsearch = require('elasticsearch'); var client = new elasticsearch.Client({ host: 'localhost:9200', log: 'trace' }); const query = eb.QueryBuilder() .query(eb.TermQuery('name', 'Kirby')) .query(eb.MatchQuery('description', 'Pink, fluffy and very hungry')) .queryMustNot(eb.TermQuery('name', 'Waddle Dee')); // stringifying the object will give the following result // JSON.stringify(query) // { // "bool": { // "must": [{ // "term": { // "name": "Kirby" // } // }, { // "match": { // "description": { // "query": "Pink, fluffy and very hungry" // } // } // }], // "must_not": { // "term": { // "name": "Waddle Dee" // } // } // } // } // but the created query can be passed without doing stringify, since the Elasticsearch client will stringify it internally after client.search({ index: 'games', type: 'dreamland', body: { query: query } }, function(err, resp) { // result of the search here ... }); ``` ## Used as a global module (REPL) All the query classes have been exposed to the REPL so they can be called directly. ```zsh $ es-builder es-builder> query = QueryBuilder().query(TermQuery('name', 'Kirby')).query(MatchQuery('description', 'Pink, fluffy and very hungry')).queryMustNot(TermQuery('name', 'Waddle Dee')); es-builder> query.stringified '{"bool":{"must":[{"term":{"name":{"value":"Kirby"}}},{"match":{"description":{"query":"Pink, fluffy and very hungry"}}}],"must_not":{"term":{"name":{"value":"Waddle Dee"}}}}}' es-builder> .exit ``` Copy the result above and paste it in your curl search request: ```zsh $ curl -XGET 'http://localhost:9200/games/dreamland/_search' -d' { "query" : {"bool":{"must":[{"term":{"name":{"value":"Kirby"}}},{"match":{"description":{"query":"Pink, fluffy and very hungry"}}}],"must_not":{"term":{"name":{"value":"Waddle Dee"}}}}} }' ``` ## Filter context Adding clauses to filter context is possible as well: ```js query.filter(eb.TermQuery('name', 'Kirby')); // stringifying the object will give the following result // JSON.stringify(query) // { // "bool": { // "filter": { // "term": { // "name": "Kirby" // } // } // } // } ``` ## Shortcut for leaf query clauses There is a shortcut available for leaf query clauses when used as a local module, inspired by [elasticsearch-dsl-py](https://github.com/elastic/elasticsearch-dsl-py): ```js const Q = eb.Q; const TermsQuery = eb.TermsQuery; // doing this Q('terms', 'name', ['Kirby', 'Metaknight']); // equals TermsQuery('name', ['Kirby', 'Metaknight']) // both giving the same result: // { // "terms": { // "name": ["Kirby", "Metaknight"] // } // } ``` Also, there is a one-to-one mapping relation between the raw query and its equivalent in the DSL, therefore adding directly raw queries as Javascript objects is fine. ```js const eb = require('es-builder'); eb.QueryBuilder().query({ terms: name: ['Kirby', 'Metaknight'] }).built; // same result: // // { // bool: { // must: { // terms: { // name: [ 'Kirby', 'Metaknight' ] // } // } // } // } // } ``` ## Complex queries Combined queries can be built nesting compound query clauses. ```js const eb = require('es-builder'); const Q = eb.Q; const query = eb.QueryBuilder(); // add a couple of filters query .filter(Q('terms', 'name', ['Kirby', 'Metaknight'])) .filter(Q('exists', 'age')); // create a bool compound query const boolQuery = eb.BoolQuery() .should(Q('range', 'age').gt(20).lt(25)) .should(Q('prefix', 'surname', 'Ki')); // nest it query.filter(boolQuery); // stringifying the object will give the following result // JSON.stringify(query) // { // "bool": { // "filter": { // bool: { // "must": [{ // "terms": { // "name": { // "value": ["Kirby", "Metaknight"] // } // } // }, { // "exists": { // "field": "age" // } // }, { // "bool": { // "should": [{ // "range": { // "age": { "gt": 20, "lt": 25 } // } // }, { // "prefix": { // "surname": { // "value": "Ki" // } // } // }] // } // }] // } // } // } // } ``` ## Aliases There are aliases available for some methods. `const queryBuilder = eb.QueryBuilder();` - `queryBuilder.query()` → `queryBuilder.queryAnd()` - `queryBuilder.queryMustNot()` → `queryBuilder.queryNot()` - `queryBuilder.queryShould()` → `queryBuilder.queryOr()` - `queryBuilder.filter()` → `queryBuilder.filterAnd()` - `queryBuilder.filterMustNot()` → `queryBuilder.filterNot()` - `queryBuilder.filterShould()` → `queryBuilder.filterOr()` `const boolQuery = eb.BoolQuery();` - `boolQuery.must()` → `boolQuery.and()` - `boolQuery.mustNot()` → `boolQuery.not()` - `boolQuery.should()` → `boolQuery.or()` # API Coming soon. At the moment you can take a look to the tests to see how all the methods work. # Compatibility - Compatible with Elasticsearch 2.x search API - Node.js version - As a required module: It has been transpiled to ES5 using [Babel](https://babeljs.io/), so it is compatible with old Node.js versions (> 0.12.0) - As a global module (REPL): > 6.0.0 # ToDo List - Add leaf query clauses like `multi_match` or `fuzzy` - Add compound query clauses like `constant_score` or `dis_max` - Allow passing array of filter objects in compound query clauses - Browser compatible - And more Pull requests or any comments are more than welcome.