An elasticsearch query body builder.
npm install bodybuilderAn elasticsearch query body builder. Easily build complex queries for
elasticsearch with a simple, predictable api.
Check out the API documentation for details and examples.
Use https://bodybuilder.js.org/ to test your constructions.
Currently aims to support the full elasticsearch query DSL for all versions.
The elasticsearch 1.x query DSL is supported by providing a v1 argument
when calling the build function.
npm install bodybuilder --save
``js`
var bodybuilder = require('bodybuilder')
var body = bodybuilder().query('match', 'message', 'this is a test')
body.build() // Build 2.x or greater DSL (default)
body.build('v1') // Build 1.x DSL
For each elasticsearch query body, create an instance of bodybuilder, applybuild
the desired query/filter/aggregation clauses, and call to retrieve the
built query body.
Try it out on the command line using the node REPL:
# Start the repl
node ./node_modules/bodybuilder/repl.js
# The builder is available in the context variable bodybuilder
bodybuilder > bodybuilder().query('match', 'message', 'this is a test').build()
`js`
bodybuilder().query([arguments])
Creates a query of type queryType.
#### Arguments
The specific arguments depend on the type of query, but typically follow this
pattern:
* queryType - The name of the query, such as 'term' or 'prefix'.fieldToQuery
* - The name of the field in your index to query over.searchTerm
* - The string to search for.
`js`
var body = bodybuilder().query('match', 'message', 'this is a test').build()
// body == {
// query: {
// match: {
// message: 'this is a test'
// }
// }
// }
`js`
bodybuilder().filter([arguments])
Creates a filtered query using filter of type filterType.
#### Arguments
The specific arguments depend on the type of filter, but typically follow this
pattern:
* filterType - The name of the query, such as 'regexp' or 'exists'.fieldToQuery
* - The name of the field in your index to filter on.searchTerm
* - The string to search for.
`js`
bodybuilder().filter('term', 'message', 'test').build()
// body == {
// query: {
// bool: {
// filter: {
// term: {
// message: 'test'
// }
// }
// }
// }
// }
`js`
bodybuilder().aggregation([arguments])
Creates an aggregation of type aggregationType.
#### Arguments
The specific arguments depend on the type of aggregation, but typically follow
this pattern:
* aggregationType - The name of the aggregation, such as 'sum' or 'terms'.fieldToAggregate
* - The name of the field in your index to aggregate over.aggregationName
* - (optional) A custom name for the aggregation. Defaults toagg_.aggregationOptions
* - (optional) Additional key-value pairs to include in thenestingFunction
aggregation object.
* - (optional) A function used to define aggregations as
children of the one being created. This _must_ be the last parameter set.
`js`
var body = bodybuilder().aggregation('terms', 'user').build()
// body == {
// aggregations: {
// agg_terms_user: {
// terms: {
// field: 'user'
// }
// }
// }
// }
#### Nested aggregations
To nest aggregations, pass a function as the last parameter in [arguments].function
The receives the recently built aggregation instance and is expectedObject
to return an which will be assigned to .aggs on the current.aggregation([arguments])
aggregation. Aggregations in this scope behave like builders and you can call
the chainable method on them just as you would onbodybuilder
the main .
`js`
var body = bodybuilder().aggregation('terms', 'code', {
order: { _term: 'desc' },
size: 1
}, agg => agg.aggregation('terms', 'name')).build()
// body == {
// "aggregations": {
// "agg_terms_code": {
// "terms": {
// "field": "code",
// "order": {
// "_term": "desc"
// },
// "size": 1
// },
// "aggs": {
// "agg_terms_name": {
// "terms": {
// "field": "name"
// }
// }
// }
// }
// }
//}
`js`
bodybuilder().suggest([arguments])
Creates a phrase or term suggestion.
#### Arguments
The specific arguments depend on the type of aggregation, but typically follow
this pattern:
* suggestionType - This can be either phrase or term.fieldToAggregate
* - The name of the field in your index to suggest on.options
* - An object of fields to include in the suggestions.text
* - The query to run on our suggest field.name
* - A custom name for the suggest clause.analyzer
* - The name of an analyzer to run on a suggestion.
* ... other suggest specific options, see typings or the ElasticSearch suggest docs for more info
`js`
var body = bodybuilder().suggest('term', 'user', { text: 'kimchy', 'name': 'user_suggest'}).build()
// body == {
// aggregations: {
// user_suggest: {
// text: 'kimchy',
// term: {
// field: 'user'
// }
// }
// }
// }
Multiple queries and filters are merged using the boolean query or filter (see
Combining Filters).
`js
var body = bodybuilder()
.query('match', 'message', 'this is a test')
.filter('term', 'user', 'kimchy')
.filter('term', 'user', 'herald')
.orFilter('term', 'user', 'johnny')
.notFilter('term', 'user', 'cassie')
.aggregation('terms', 'user')
.suggest('term', 'user', { text: 'kimchy' })
.build()
// body == {
// query: {
// bool: {
// must: {
// match: {
// message: 'this is a test'
// }
// },
// filter: {
// bool: {
// must: [
// {term: {user: 'kimchy'}},
// {term: {user: 'herald'}}
// ],
// should: [
// {term: {user: 'johnny'}}
// ],
// must_not: [
// {term: {user: 'cassie'}}
// ]
// }
// }
// },
// },
// aggs: {
// agg_terms_user: {
// terms: {
// field: 'user'
// }
// }
// }
// suggest_term_user: {
// text: 'kimchy',
// term: {
// field: 'user'
// }
// }
// }
`
#### Nesting Filters and Queries
It is even possible to nest filters, e.g. when some should and must filters have to be combined.
`js
var body = bodybuilder()
.orFilter('term', 'author', 'kimchy')
.orFilter('bool', b => b
.filter('match', 'message', 'this is a test')
.filter('term', 'type', 'comment')
)
.build()
// body == {
// query: {
// bool: {
// filter: {
// bool: {
// should: [
// { term: { author: 'kimchy' } },
// { bool: { must: [
// { match: { message: 'this is a test' } },
// { term: { type: 'comment' } }
// ] } }
// ]
// }
// }
// }
// }
// }
`
Set a sort direction using sort(field, direction), where direction defaults to
ascending.
`js
var body = bodybuilder()
.filter('term', 'message', 'test')
.sort('timestamp', 'desc')
.sort([{
"channel": {
"order": "desc"
}
}])
.sort([
{"categories": "desc"},
{"content": "asc"}
])
.build()
// body == {
// sort: [{
// "timestamp": {
// "order": "desc"
// }
// },
// {
// "channel": {
// "order": "desc"
// }
// },
// {
// "categories": {
// "order": "desc"
// }
// },
// {
// "content": {
// "order": "asc"
// }
// }
// ],
// query: {
// bool: {
// filter: {
// term: {
// message: 'test'
// }
// }
// }
// }
// }
`sort(field, { sort: 'asc', mode: 'min', ...})
Advanced usage: Set a sort configuration object for the given sort field with additional sort properties.
Set from and size parameters to configure the offset and maximum hits to be
returned.
`js
var body = bodybuilder()
.filter('term', 'message', 'test')
.size(5)
.from(10)
.build()
// body == {
// size: 5,
// from: 10,
// query: {
// bool: {
// filter: {
// term: {
// message: 'test'
// }
// }
// }
// }
// }
`
Set any other search request option using rawOption passing in the key-value
pair to include in the body.
`js
var body = bodybuilder()
.filter('term', 'message', 'test')
.rawOption('_sourceExclude', 'verybigfield')
.build()
// body == {
// _sourceExclude: 'verybigfield',
// query: {
// bool: {
// filter: {
// term: {
// message: 'test'
// }
// }
// }
// }
// }
``
Run unit tests:
npm test
Thanks goes to these wonderful people (emoji key):
|
Daniel Paz-Soldan
π» π π") π€ |
NicolΓ‘s Fantone
π» β οΈ |
Nauval Atmaja
π» |
Ferron H
π» β οΈ π π |
Dave Cranwell
π» |
Johannes Scharlach
π» π π€ |
Anton Samper Rivaya
π» π |
| :---: | :---: | :---: | :---: | :---: | :---: | :---: |
|
Suhas Karanth
π¬ |
Jacob Gillespie
π» |
This project follows the all-contributors specification. Contributions of any kind welcome!