Giter Site home page Giter Site logo

danpaz / bodybuilder Goto Github PK

View Code? Open in Web Editor NEW
1.2K 29.0 127.0 3.25 MB

An elasticsearch query body builder :muscle:

Home Page: http://bodybuilder.js.org

License: MIT License

JavaScript 77.44% HTML 3.45% CSS 9.86% TypeScript 9.25%
elasticsearch querydsl builder javascript hacktoberfest

bodybuilder's Introduction

bodybuilder

All Contributors npm version Build Status

An elasticsearch query body builder. Easily build complex queries for elasticsearch with a simple, predictable api.

bodybuilder

Documentation

Check out the API documentation 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

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

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.
var body = bodybuilder().query('match', 'message', 'this is a test').build()
// body == {
//   query: {
//     match: {
//       message: 'this is a test'
//     }
//   }
// }

Filters

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.
bodybuilder().filter('term', 'message', 'test').build()
// body == {
//   query: {
//     bool: {
//       filter: {
//         term: {
//           message: 'test'
//         }
//       }
//     }
//   }
// }

Aggregations

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_<aggregationType>_<fieldToAggregate>.
  • 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.
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.

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

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

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.

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.

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. sort(field, { sort: 'asc', mode: 'min', ...})

From / Size

Set from and size parameters to configure the offset and maximum hits to be returned.

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.

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


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!

bodybuilder's People

Contributors

0xflotus avatar alexis-anzieu-ssense avatar antonsamper avatar avelis avatar danpaz avatar davidrouyer avatar deleted avatar dependabot[bot] avatar dougmoscrop avatar ferronrsmith avatar impy88 avatar jacobwgillespie avatar jcurtis avatar jenyapoyarkov avatar jgbarah avatar johannes-scharlach avatar kud avatar lukastaegert avatar msanguineti avatar nfantone avatar npatmaja avatar quinnlangille avatar sophy21r avatar stefoodle avatar yandavid avatar yanivd avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

bodybuilder's Issues

Question regarding nested filters being used outside a `must` clause

First off, thanks for the great module! Regarding nested filters, it seems as though the default behaviour is to have them all placed underneath a must clause? Separately, it seems that to use a bool filter you must provide the fully formed filter itself?

As such, trying to use multiple nested filters inside a should clause becomes cumbersome (unless I'm missing something, which I might be). Is there a better way to combine these two in order to get something along the lines of:

{
  "query": {
    "filtered": {
      "filter": {
        "bool": {
          "should": [
            {
              "nested": {
                "path": "$PATH",
                "filter": { "term": {"$TERM": "$VAL_1"} }
              }
            },
            {
              "nested": {
                "path": "$PATH",
                "filter": { "term": {"$TERM": "$VAL_2"} }
              }
            }
          ]
        }
      }
    }
  }
}

If not, would you be opposed to exposing some sort of filter builder (to allow creating the nested filter using the builder pattern) to pass constructed filters to the bool filter?

rawOption value can be object or an array

/**
   * Set any key-value on the elasticsearch body.
   *
   * @param  {String} k Key.
   * @param  {String} v Value.
   * @returns {Bodybuilder} Builder class.
   */
  rawOption(k, v) {
    this._body[k] = v
    return this
}

This shouldn't necessarily be a string, it can also be an object or an array as shown below:

new BodyBuilder().rawOption('_source', {
        "includes": [ "obj1.*", "obj2.*" ],
        "excludes": [ "*.description" ]
 });

or

new BodyBuilder().rawOption('_source',  [ "obj1.*", "obj2.*" ]);

Immutability

Question on future plan. Do you want building query to be immutable:

let query2 = query1.filter(); // create new object
// query2 !== query1

or mutable?

let query2 = query1.filter(); // update the same object
// query2 === query1 same object

Multiple .query should use 'should' instead of 'must'

Imagine the situation you want to boost the results where title matches but you also want to search for the content of the document with a smaller boost.

This scenario requires multiple match as described here https://www.elastic.co/guide/en/elasticsearch/guide/current/multi-query-strings.html.

Using should the ES will use OR, but using must the document must contain in all matches the search, which is not the case if I only have the match on title.

new Bodybuilder()
        .query('match', 'title', { "query": 'super important', boost: 3 })
        .query('match', 'content', { "query": 'super important', boost: 2 })
        .build('v2')
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "title": {
              "query": "super important",
              "boost": 3
            }
          }
        },
        {
          "match": {
            "content": {
              "query": "super important",
              "boost": 2
            }
          }
        }
      ]
    }
  }
}

Nested Aggregation

Hi, I'm looking a way to create a nested aggregation query, but I can't find how to do it yet. Am I missing something when I'm reading the documentation or currently it is not supported yet?

Is there a GUI based version?

Hello!

I'm searching for a GUI based querybuild for elasticsearch 2.x. As far as I can see your tool is the only one that can generate queries for 2.x and is written in JS.

(Edit: I found other libraries that can create es 2.x queries, but your solution seems to be the best. In my opinion)

Is there a GUI based version? If not, what do you think does it take to build a GUI on top of this lib?

Greetings
Daniel

Create Bucket Scripts

Referring to #63 to add bucket scripts in a query, #65 suggests that we can actually add them. Can anyone guide me on how to do the same?

Building filter with existsFilter doesn't take 3th parameter

I am trying to build a filter for querying elastic search hosted on bonsai and when I am building my filter, results is not what it supposed to be. It seems that it doesn't take 3th parameter and it print
"field": "field" instead of "field": "rate"

var body = new Bodybuilder()
body.filter('exists', 'field', 'rate')
body = body.build()
console.log(JSON.stringify(body))

Console log:
{"query":{"filtered":{"filter":{"exists":{"field":"field"}}}}}
Expected result:
{"query":{"filtered":{"filter":{"exists":{"field":"rate"}}}}}

I followed your documentation
var body = new Bodybuilder().filter('term', 'message', 'test').build()
body == { query: { filtered: { filter: { term: { message: 'test' } } } } }

After some digging into your code it seems that method filter is using this:
export default function existsFilter(field) { return { exists: { field } } }

Instead of this:
export default function existsFilter(field, term) { return { exists: { [field]: term } } }

I am running:
node version v5.7.1
npm 3.9.5
bodybuilder version: 1.15.1

Addition of bucket scripts

I want to include bucket scripts in my query but there doesn't seem to be a way to do that using bodybuilder, the query I want to achieve is something like this:
{ "aggs" : { "sales_per_month" : { "date_histogram" : { "field" : "date", "interval" : "month" }, "aggs": { "total_sales": { "sum": { "field": "price" } }, "t-shirts": { "filter": { "term": { "type": "t-shirt" } }, "aggs": { "sales": { "sum": { "field": "price" } } } }, "t-shirt-percentage": { "bucket_script": { "buckets_path": { "tShirtSales": "t-shirts>sales", "totalSales": "total_sales" }, "script": "tShirtSales / totalSales * 100" } } } } } }
Is there already a way to do so using this library and if not, can you guide me if I want to include it in the library, how should I go about doing the same, will be happy to contribute to the project.
Thanks

Nested aggregation fails when using "aggregation" as a name

This usage succeeds

new Bodybuilder()
  .aggregation('terms', 'user', 'custom-name', {size: 0}, function (agg) {
    return agg.aggregation('avg', 'metric')
  })
  .build()

while this usage fails

new Bodybuilder()
  .aggregation('terms', 'user', 'aggregation', {size: 0}, function (agg) {
    return agg.aggregation('avg', 'metric')
  })
  .build()

with the error

TypeError: aggs.aggregation is not a function

It looks like aggs.aggregation is now an object that looks like this, instead of the expected method.

{
  "terms": {
    "field": "user"
  }
}

Multiple Aggregations using loop

Referring to #62 , if I have the same array of aggregations
[{ "aggregationType:"terms", "aggregationField:"name" }, { "aggregationType:"terms", "aggregationField:"class" }]
and I want to put them all of them as multiple aggregations nested inside a parent aggregation. How do I do that?

Desired output:

{
  "aggs": {
    "location_wise": {
      "terms": {
        "field": "states"
      },
      "aggs": {
        "agg_sum_name": {
          "sum": {
            "field": "name"
          }
        },
        "agg_avg_class": {
          "avg": {
            "field": "class"
          },
        },
        "agg_value_count_grades": {
          "value_count": {
            "field": "grades"
          }
        }  
              
      }
    }
  }
} 

bodybuilder v2 ignore empty params

This bug is only present on the prerelease-bodybuilder-2 branch.

Bug:

Checking for a property to have an empty string ("") creates unwanted ES query.

// prerelease-bodybuilder-2 branch
var body = new Bodybuilder()
  .filter('term', 'name', '')
  .body.build('v2')

gives

{"query":{"bool":{"filter":{"term":{"field":"name"}}}}}

but using http://bodybuilder.js.org/ with

new Bodybuilder()
.filter('term', 'name', '')
        .build('v2')

produces:

{
  "query": {
    "bool": {
      "filter": {
        "term": {
          "name": ""
        }
      }
    }
  }
}

Filtered Queries not supported by elastic anymore(support for 5.0)

Hi,

The elastic documentation says the filtered query was depreciated in 2.0.0-beta1 (here) and removed in 5.0. However body builder by default seems to make filtered queries.

So the current format of how bodybuilder makes queries:
{
“filtered” : {
“query”: { query definition },
“filter”: { filter definition }
}
}

and the expected format now is:
{
“bool” : {
“must”: { query definition },
“filter”: { filter definition }
}
}

However I do not see any explicit way to actually write the query in Bodybuilder like this.

My Questions:

  1. Is there support, and I am missing out on something??
  2. Are you guys working on it?
  3. If not would it be ok if I give a patch for it?

Neverthless, awesome product, you guys rock :-)

Avneesh

Aggregation

Great tool,
Just wondering is it possible aggregate by Month of a date field?
Thanks
Frank

Help with deferred aggregation addition

I've got a problem I'm hoping you can help with. See: http://jsbin.com/bagarujomo/edit?html,js,output

Essentially I have two arrays of items which are not known at runtime (unlike this contrived example) and I want items in the second array to be added as sub-aggregates of particular items in the first array.

My JS around apply(), call(), partials, currying etc is rather shakey and I'm sure they're the solution here, but I was hoping you might know a quick answer to this having no doubt addressed this yourself.

Fuzzines - multi_match

Hello!

Nice lib, first of all! 👍 pleasure using it.

Is there support for

GET /my_index/my_type/_search
{
  "query": {
    "multi_match": {
      "fields":  [ "text", "title" ],
      "query":     "SURPRIZE ME!",
      "fuzziness": "AUTO"
    }
  }
}

I don't see how I can set fuzziness to anything other than AUTO (default) as https://github.com/danpaz/bodybuilder/blob/master/src/queries/multi-match-query.js#L9

Doesn't accept the custom object fields.
Maybe we can add a 4th param called extra or similar and just extend the object?

export default function multiMatchQuery(fields, query, type='best_fields', extra = {} ) {
  return {
    multi_match: {
      query: query,
      type: type,
      fields: fields,
      ...extra
    }
  }
}

I would be happy to submit a PR if this approach seems okay to you.

Thank you,
Goran

API documentation

Add jsdocs to the code and generate the new documentation using documentation.js.

npm run build:docs

Some goals for the new api docs:

  • Only show public methods in the api docs. I think those are:
    • query, orQuery, andQuery, notQuery
    • filter, orFilter, andFilter, notFilter
    • aggregation, agg
    • from, size, rawOption
    • build
  • It should read like a guide, e.g. include a small introduction at the top instead of diving straight into the api.
  • Link to it from the readme.
  • Figure out how to link to the old bodybuilder 1 documentation.

Migration guide for bodybuilder 2

Write a guide for existing users of bodybuilder to migrate their code to the new version. Include at least:

  • Reasons to update to the new version, or not to update.
  • List of breaking changes.
  • Code samples comparing the old code and the new code.

date_range not supported

Is this compatible with the latest version of elasticsearch 2.4.0 ? I've tested with the new aggregation method called date_range but failed.

Browser build

Would be great to provide a bundled/minified version of the library for use in the browser.

should nested within must

I am curious if it is possible with this module to set up a complex elastic query that has should queries nested within a must.

Simply, I am trying to recreate this SQL query:
SELECT * FROM test where status = 'active' and (city = 'New York' or city = 'Toronto')

I would like to get back something similar to the below, but I have only been able to have the MUST and the SHOULD on the same level. Is this functionality possible? It seems like a simple query case, but maybe I am wrong.

{
    "query": {
        "bool": {
            "must": {
                "bool": {
                    "must": [
                        {
                            "match": {
                                "status": {
                                    "query": "active"
                                }
                            }
                        },
                        {
                            "bool": {
                                "should": [
                                    {
                                        "match": {
                                            "city": {
                                                "query": "New York"
                                            }
                                        }
                                    },
                                    {
                                        "match": {
                                            "city": {
                                                "query": "Toronto"
                                            }
                                        }
                                    }
                                ]
                            }
                        }
                    ]
                }
            }
        }
    }
}

API proposal

I've looked at src/index.js. What do you think about below two proposals?

Object transformer style

For simple filter

import termFilter from 'xxx';

let query0 = {};

let query1 = termFilter('user', 'Daiwei', query0);

// query1:
// {
//   filtered: {
//     query: {
//       filter: {
//         term: {
//           user: 'Daiwei'
//         }
//       }
//     }
//   }
// }

query0 === query1 // -> false

For nested filters

import boolFilter from 'xxx';
import termFilter from 'xxx';

let query0 = {};

let query2 = boolFilter('must', termFilter('user', 'Daiwei'), query0);

// query2:
// {
//   filtered: {
//     query: {
//       bool: {
//         must: [
//           {
//             term: {
//               user: 'Daiwei'
//             }
//           }
//         ]
//       }
//     }
//   }
// }

Compose filters

import boolFilter from 'xxx';
import termFilter from 'xxx';
import compose from 'xxx';

let query3 = compose(
  boolFilter('must', termFilter('user', 'Daiwei'),
  boolFilter('must', termFilter('hobby', 'functional programing')
)(query0);

// query3:
// {
//   filtered: {
//     query: {
//       bool: {
//         must: [
//           {
//             term: {
//               user: 'Daiwei'
//             }
//           },
//           {
//             term: {
//               hobby: 'functional programing'
//             }
//           }
//         ]
//       }
//     }
//   }
// }

Immutable object style

import Query from 'xxx';
import termFilter from 'xxx';

let query0 = Query();

let query1 = Query.addFilter(termFilter('user', 'Daiwei'));

// query1.query:
// {
//   filtered: {
//     query: {
//       filter: {
//         term: {
//           user: 'Daiwei'
//         }
//       }
//     }
//   }
// }

query0 === query1 // -> false

Query / filter/ aggregation "X" is not supported

Right now bodybuilder depends on having a definition for every filter/query/aggregation in the elasticsearch query dsl (which is a lot). This works, and gives a high degree of control over how to construct each filter/query/aggregation clause. However,

  • The dsl is a moving target. It is not sustainable to update bodybuilder in lockstep with elasticsearch as the dsl changes.
  • It can be frustrating if bodybuilder doesn't support a particular filter/query/aggregation, and someone either has to make a PR and wait for a patch or drop bodybuilder altogether.
  • Many issues have been created to address missing filters/queries/aggregations: #64 #63 #53 #42 +++

Proposals

Some ideas I had to improve this:

  • Allow custom filter/query/aggregation clauses. Maybe it could look something like:
new Bodybuilder().filter('custom', { ... })
or
new Bodybuilder().rawFilter({ ... })

This way bodybuilder can continue to be useful while users wait for a PR to add their definition is merged.

  • Generalize the filter/aggregation/query builders such that maybe we don't need definitions for individual clauses at all. Most clauses follow a predictable structure. Example:
.filter(<type>, <field>, <value>)
becomes
{
  <type> {
    <field>: <value>
  }
}

// Example
.filter('term', 'user', 'kimchy')
becomes
{
  term: {
    user: 'kimchy'
  }
}

Still thinking these ideas through and looking for feedback from anyone on this!

Support for Scripted Metric aggregation

Thanks for making this library. I am interested in using this library but noticed no support for the scripted_metric aggregation. Looking at the docs I can see also fitting into this framework along with any other aggregation.

I don't mind attempting a PR but there is a challenge in the required parameters for this aggregation (open to suggestions).

Comprehensive tests for queries, filters, aggregations

The goal is for bodybuilder 2 to have a comprehensive unit test suite such that anyone can look at a test to see an example of how to build their particular query/filter/aggregation. This is more important in the new version of bodybuilder because the api documentation will no longer have definitions for the supported clauses.

filter query issue

when i hit new Bodybuilder().filter('term', 'message', 'test').build('v2') , I used to get
{ query: { bool: { filter: [Object] } } } . Object is returning which needs to be a string.

am I doing anything wrong. I am using elasticsearch 2.3.1 version.

Verbose debug logging

Since the version 1.15.0, our ci breaks because of too much output.

The console looks like this :

DEBUG function j(agg) {
    return agg.aggregation('terms', 'xxx', 'xxx', { size: _get__('DEFAULT_AGG_SIZE'), order: _get__('DEFAULT_ORDER'), missing: _get__('MISSING_NUMBER') }, sum);
  } { xxx:
   { terms:
      { field: 'xxx',
        size: 400000,
        order: [Object],
        missing: 'none' } },
  _aggs: { xxx: { terms: [Object], aggs: [Object] } } } { xxx:
   { terms:
      { field: 'xxx',
        size: 400000,
        order: [Object],
        missing: 'none' } },
  _aggs: { xxx: { terms: [Object], aggs: [Object] } } }
DEBUG function sum(agg) {
    return agg.aggregation('sum', 'xxx', 'xxx').aggregation('sum', 'xxx', 'xxx').aggregation('sum', 'xxx', 'xxx').aggregation('sum', 'xxx', 'xxx
external')[…].aggregation('sum', 'xxx', 'xxx'
).aggregation('sum', 'xxx ', 'xxx').aggregation('avg', 'xxx', 'xxx').aggregation('sum', 'xxx', 'xxx');
  } { xxxx:
   { terms:
      { field: 'xxxx',
        size: 400000,
        order: [Object],
        missing: -1 } },
  _aggs:
   { xxx: { sum: [Object] },
     xxx: { sum: [Object] },
     xxx: { sum: [Object] },,
[…]

The new logo has arrived.

It's raining here, quite profusely. I just finished watching the Battle of Chemulpo Bay. It's a silent film that was developed in 1904. Much like the current bodybuilder logo, I felt that it lacked expression. It looks like the current logo is just an enlarged JPEG of the flex emoji. So I immediately thought, we can do better than that!

Two years ago I purchased a book from Amazon titled The Book of GIMP: A Complete Guide to Nearly Everything. Much to my dismay, it does a very poor job at covering nearly everything. I dusted it off and read a couple chapters with my morning tea (I only drink decaffeinated Japanese-style sencha tea now since my ordeal, but that's a story for another issue).

I decided to flex my GIMP skills a bit and produce a new logo for the project. There's still room for improvement, but it's original and pretty damn classy if I do say so myself.

Juliette Aristides once said, "Often the most unique, compelling work comes not from a concept or an idea but from a deep, wordless place inside the artist."

I believe that when you look into this logo you will find a little piece of me inside.

bodybuilder

Are queries like these possible?

I am looking for nested aggregations which have some more aggregations alongside them.
For example:
{ "query":{ "bool":{ "filter":{ "range":{ "@timestamp":{ "from":1, "to":5 } } }, "should":[ { "query_string":{ "query":"*" } } ] } }, "aggs":{ "time-interval":{ "date_histogram":{ "field":"@timestamp", "interval":"1y" }, "aggs":{ "Terms-Agg-0":{ "terms":{ "field":"topLvlField", "size":10 }, "aggs":{ "Extended-Stat-Agg":{ "extended_stats":{ "field":"units" } }, "Terms-Agg-1":{ "terms":{ "field":"nestedAggField", "size":10 }, "aggs":{ "Extended-Stat-Agg":{ "extended_stats":{ "field":"units" } } } } } } } } } }

The above query has one level of nesting. It also asks for extended stats on a field, at both levels.
I am able to nest, but not able to add extended stats. Does this require an enhancement, or am i missing something in the syntax?

Support for pipelined aggregations?

Hi,

This library is really helpful in creating Elasticsearch queries. But in my application, I have many pipelined aggregations like moving average, cumulative sum etc, derivative etc. I haven't come across any doc describing them. Can you please help me with those?

Thanks in Advance

License?

I'd love to use your library but my project requires the software to have a license of some type, does this project have a license?

Script Fields on Aggregation

Is there currently a way to use script properties instead of fields on aggregation? like the following example :

"aggs": { "Balance": { "sum": { "script": "doc['DEBIT_DC'].value + doc['CREDIT_DC'].value", "lang": "expression" } } }

Nested aggregation using a loop

Suppose if I have a list of aggregations which I want to nest in an array, how should I go about being able to do that since it expects a parameter for the nested aggregations which means that I'll have to put all the aggregations in the single expression itself and I can't do it by iterating over the loop and inserting the nested aggregations somehow, any other way to achieve this?

Difference in output in multiline vs single line expression

When I run BodyBuilder using single line expression such as:
var body = new BodyBuilder() .aggregation('terms', "xAxis", 'location_wise') .aggregation('stats', 'number of schools', 'stats') .build();
I get the result like this:
{ "aggregations": { "location_wise": { "terms": { "field": "xAxis" } }, "stats": { "stats": { "field": "number of schools" } } } }

But if I use multi line expression like this:
var body = new BodyBuilder(); body.aggregation('avg', 'fieldName','location_wise'); body.aggregation('stats','fieldName','stats'); body.build();
I get result like this:
{ "_body": {}, "_filters": {}, "_queries": {}, "_aggBuilder": { "_aggs": { "location_wise": { "avg": { "field": "fieldName" } }, "stats": { "stats": { "field": "fieldName" } } } } }
How can I get result like in the first case using multi line expressions to generate the query?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.