npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

es-builder

v0.5.0

Published

Elasticsearch query builder for Node.js

Downloads

393

Readme

Elasticsearch Query Builder

Build Status

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.

Installation

The package can be installed as a local module, to be required in your code.

npm install es-builder

Also, it can be installed globally, ready to be used through the Node.js REPL.

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:

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.

$ 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:

$ 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:

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:

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.

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.

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, 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.