Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/danpaz/bodybuilder
An elasticsearch query body builder :muscle:
https://github.com/danpaz/bodybuilder
builder elasticsearch hacktoberfest javascript querydsl
Last synced: 24 days ago
JSON representation
An elasticsearch query body builder :muscle:
- Host: GitHub
- URL: https://github.com/danpaz/bodybuilder
- Owner: danpaz
- License: mit
- Created: 2015-08-11T03:27:19.000Z (about 9 years ago)
- Default Branch: master
- Last Pushed: 2023-07-19T15:24:29.000Z (over 1 year ago)
- Last Synced: 2024-05-22T23:03:01.706Z (6 months ago)
- Topics: builder, elasticsearch, hacktoberfest, javascript, querydsl
- Language: JavaScript
- Homepage: http://bodybuilder.js.org
- Size: 3.17 MB
- Stars: 1,238
- Watchers: 29
- Forks: 127
- Open Issues: 10
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- Funding: .github/FUNDING.yml
- License: LICENSE.md
Awesome Lists containing this project
- awesome-elasticsearch - Bodybuilder
- elasticsearch-collection - Bodybuilder
README
# bodybuilder
[![All Contributors](https://img.shields.io/badge/all_contributors-9-orange.svg?style=flat-square)](#contributors)
[![npm version](https://badge.fury.io/js/bodybuilder.svg)](https://www.npmjs.com/package/bodybuilder)
[![Build Status](https://travis-ci.org/danpaz/bodybuilder.svg?branch=master)](https://travis-ci.org/danpaz/bodybuilder)An elasticsearch query body builder. Easily build complex queries for
elasticsearch with a simple, predictable api.![bodybuilder](img/bodybuilder.jpeg)
# Documentation
**Check out the [API documentation](http://bodybuilder.js.org/docs)** for details and examples.
Use https://bodybuilder.js.org/ to test your constructions.
## Elasticsearch compatibility
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.## Install
npm install bodybuilder --save
## Usage
```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`, apply
the desired query/filter/aggregation clauses, and call `build` to retrieve the
built query body.## REPL
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()### Queries
```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'
// }
// }
// }
```### Filters
```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'
// }
// }
// }
// }
// }
```### Aggregations
```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 to
`agg__`.
* `aggregationOptions` - (optional) Additional key-value pairs to include in the
aggregation object.
* `nestingFunction` - (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]`.
The `function` receives the recently built aggregation instance and is expected
to return an `Object` which will be assigned to `.aggs` on the current
aggregation. Aggregations in this scope behave like builders and you can call
the chainable method `.aggregation([arguments])` on them just as you would on
the main `bodybuilder`.```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"
// }
// }
// }
// }
// }
//}
```### Suggestions
```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]('./bodybuilder.d.ts') or the [ElasticSearch suggest docs](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-suggesters.html) 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'
// }
// }
// }
// }
```### Combining queries, filters, aggregations, and suggestions
Multiple queries and filters are merged using the boolean query or filter (see
[Combining Filters](https://www.elastic.co/guide/en/elasticsearch/guide/current/combining-filters.html)).```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' } }
// ] } }
// ]
// }
// }
// }
// }
// }
```### Sort
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'
// }
// }
// }
// }
// }
```
**Advanced usage:** Set a sort configuration object for the given sort field with additional [sort properties](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-sort.html).
`sort(field, { sort: 'asc', mode: 'min', ...})`### From / Size
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'
// }
// }
// }
// }
// }
```### Other Options
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'
// }
// }
// }
// }
// }
```## Test
Run unit tests:
npm test
## Contributors
Thanks goes to these wonderful people ([emoji key](https://github.com/kentcdodds/all-contributors#emoji-key)):
| [
Daniel Paz-Soldan](http://danpaz.me/)
[π»](https://github.com/danpaz/bodybuilder/commits?author=danpaz "Code") [π](https://github.com/danpaz/bodybuilder/commits?author=danpaz "Documentation") [π](#infra-danpaz "Infrastructure (Hosting, Build-Tools, etc)") [π€](#ideas-danpaz "Ideas, Planning, & Feedback") | [
NicolΓ‘s Fantone](https://github.com/nfantone)
[π»](https://github.com/danpaz/bodybuilder/commits?author=nfantone "Code") [β οΈ](https://github.com/danpaz/bodybuilder/commits?author=nfantone "Tests") | [
Nauval Atmaja](http://nauvalatmaja.com)
[π»](https://github.com/danpaz/bodybuilder/commits?author=npatmaja "Code") | [
Ferron H](https://ferronrsmith.github.io/)
[π»](https://github.com/danpaz/bodybuilder/commits?author=ferronrsmith "Code") [β οΈ](https://github.com/danpaz/bodybuilder/commits?author=ferronrsmith "Tests") [π](https://github.com/danpaz/bodybuilder/issues?q=author%3Aferronrsmith "Bug reports") [π](https://github.com/danpaz/bodybuilder/commits?author=ferronrsmith "Documentation") | [
Dave Cranwell](http://davecranwell.com)
[π»](https://github.com/danpaz/bodybuilder/commits?author=davecranwell "Code") | [
Johannes Scharlach](https://github.com/johannes-scharlach)
[π»](https://github.com/danpaz/bodybuilder/commits?author=johannes-scharlach "Code") [π](https://github.com/danpaz/bodybuilder/commits?author=johannes-scharlach "Documentation") [π€](#ideas-johannes-scharlach "Ideas, Planning, & Feedback") | [
Anton Samper Rivaya](https://rivaya.com)
[π»](https://github.com/danpaz/bodybuilder/commits?author=antonsamper "Code") [π](https://github.com/danpaz/bodybuilder/commits?author=antonsamper "Documentation") |
| :---: | :---: | :---: | :---: | :---: | :---: | :---: |
| [
Suhas Karanth](https://github.com/sudo-suhas)
[π¬](#question-sudo-suhas "Answering Questions") | [
Jacob Gillespie](https://github.com/jacobwgillespie)
[π»](https://github.com/danpaz/bodybuilder/commits?author=jacobwgillespie "Code") |This project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification. Contributions of any kind welcome!