elastic-builder

repository·master·Indexed 19 days ago

https://github.com/sudo-suhas/elastic-builder

A JavaScript implementation of the Elasticsearch Query DSL for Node.js and browser environments. It provides a fluent builder syntax to programmatically construct complex search request bodies, designed to work seamlessly with the official Elasticsearch JavaScript client. The library supports both class-based instantiation and helper methods, and includes a comprehensive suite of builders for metrics, bucket, pipeline, and matrix aggregations.

Tokens
37.6K
Snippets
145
Records
198
Agent score
67%

What's inside elastic-builder

  1. Two ways to construct queries in elastic-builder

    master

    You can build Elasticsearch queries using two distinct patterns:

    1. Class Constructors: Use the new keyword with specific class names (e.g., new esb.RequestBodySearch()).
    2. Helper Methods: Use lowercase helper functions (e.g., esb.requestBodySearch()) which construct the objects without requiring the new keyword.

    Both methods result in an object that can be converted to JSON via .toJSON().

    // Pattern 1: Class Constructors
    const requestBody = new esb.RequestBodySearch()
        .query(new esb.MatchQuery('message', 'this is a test'));
    
    // Pattern 2: Helper Methods
    const requestBody = esb.requestBodySearch()
        .query(esb.matchQuery('message', 'this is a test'));
  2. Understand the elastic-builder project structure

    master

    The project is organized into several key directories that define how the library is consumed:

    • src/: Contains the core ES6 source files. The code in this folder does not use ES6 imports, allowing it to be used directly without transpilation.
    • browser/: Contains the minified UMD module intended for browser environments.
    • index.d.ts: Provides TypeScript type definitions for the library.
    • repl.js: The entry point for the REPL (Read-Eval-Print Loop) environment.

    When importing from elastic-builder/src, you can access both the concrete classes and the helper methods provided by the entry point.

  3. How to instantiate queries and aggregations

    master

    The library provides two ways to create queries and aggregations via the index.js entry point. This is designed to support both class-based instantiation and a more concise functional approach.

    1. Class-based: Use the new keyword with the exported classes (e.g., new esb.MatchQuery()). This is the approach reflected in the official documentation and type definitions.
    2. Helper methods: Use the shorthand methods attached to the esb object (e.g., esb.matchQuery()). These methods instantiate the classes for you, allowing you to avoid the new keyword.

    Both methods result in the same underlying object structure.

    // Using the class constructor
    const query = new esb.MatchQuery();
    
    // Using the helper method (shorthand)
    const query = esb.matchQuery();
  4. Understand the class inheritance model

    master

    The library relies heavily on ES6 class inheritance. Core logic for request bodies, queries, and aggregations is located in the core directory.

    • Organization: Queries and aggregations are organized to mirror the official Elasticsearch reference guide.
    • Base Classes: Common behavior is abstracted into base classes. While these base classes are technically instantiable, they are not exported and are intended to be used via their specialized subclasses.
    • Inheritance Chains: Some classes follow deep inheritance paths. For example, a MatchPhraseQuery follows this hierarchy: Query -> FullTextQueryBase -> MonoFieldQueryBase -> MatchPhraseQueryBase -> MatchPhraseQuery.
  5. Run the elastic-builder REPL

    master

    You can interactively test queries using the built-in Node.js REPL. The builder instance is available in the global context as esb.

    # Start the repl
    node ./node_modules/elastic-builder/repl.js
    
    # Inside the REPL
    esb.prettyPrint(esb.requestBodySearch().query(esb.matchQuery('message', 'test')));
  6. Basic usage of elastic-builder

    master

    You can use elastic-builder by either using utility functions (which avoid the new keyword) or by instantiating classes directly. The utility functions are generally preferred for cleaner code. Use .toJSON() to convert the built object into a plain JSON object suitable for Elasticsearch requests, or esb.prettyPrint(requestBody) to print a formatted version to the console.

    const esb = require('elastic-builder'); // the builder
    
    const requestBody = esb.requestBodySearch()
      .query(esb.matchQuery('message', 'this is a test'));
    
    requestBody.toJSON();
    // Output:
    // {
    //   "query": {
    //     "match": {
    //       "message": "this is a test"
    //     }
    //   }
    // }
  7. Publish a new version to npm

    master

    To publish a new version of the package to npm, follow these steps to ensure the master branch is synchronized, you are authenticated, and the version is correctly bumped and pushed. Note that the automated CI process (Travis CI) is responsible for the final publication to npm once the version bump is pushed to GitHub.

    1. Sync the master branch: Ensure your local master branch is up to date.
      git checkout master && git pull && git status
    2. **Verify npm authentication**: Confirm you are logged in as the correct user.
       ```bash
    npm whoami
    1. Bump the version: Use the npm version command to increment the version. This command triggers local tests, style checks, builds the files, commits the built files to the master branch, creates a tagged version commit, and pushes to GitHub.
      npm version major

    OR

    npm version minor

    OR

    npm version patch

    npm version major
  8. Install and use elastic-builder

    master

    To use elastic-builder to construct Elasticsearch request bodies, import the library and use either class constructors with the new keyword or the provided helper methods. After constructing your query, call .toJSON() to generate the final JSON object for your Elasticsearch request.

    If you are using Node.js version 6 or above, you can bypass the transpiled files and import directly from the src directory for potentially faster loading or direct source access.

    // Standard usage
    const esb = require('elastic-builder');
    
    // Using helper methods (recommended)
    const requestBody = esb.requestBodySearch()
        .query(esb.matchQuery('message', 'this is a test'));
    
    // Generate the JSON
    const json = requestBody.toJSON();
  9. Use elastic-builder to construct Elasticsearch queries

    master

    The elastic-builder library provides a fluent API to construct complex Elasticsearch JSON request bodies. It exports both Class-based constructors (e.g., MatchQuery) and convenience wrapper functions (e.g., matchQuery) that simplify object instantiation.

    Commonly used components include:

    • Queries: Full-text, term-level, compound, geo, span, and vector queries.
    • Aggregations: Metrics, bucket, pipeline, and matrix aggregations.
    • Suggesters: Term, phrase, and completion suggesters.
    • Core Components: Sort, Highlight, Rescore, and InnerHits.

    Most components are available via the esb namespace if using the REPL, or by importing the package in your code.

  10. Extend the Aggregation class for custom aggregations

    master

    The Aggregation class is the base implementation for all aggregation types in elastic-builder. While you should typically use the built-in aggregation builders provided by the library, you can extend this class if you need to implement a custom Elasticsearch aggregation type.

    When extending Aggregation, ensure you call the constructor with a name and an aggType. The class uses type validation, so any custom implementation must be an instance of Aggregation to be compatible with methods like .aggregation() or .aggs() on other aggregation objects.

    // Example of how one might extend the base class
    class MyCustomAggregation extends Aggregation {
        constructor(name, field) {
            super(name, 'my_custom_type');
            // custom initialization
        }
    }