{"id":13783228,"url":"https://github.com/sudo-suhas/elastic-builder","last_synced_at":"2025-05-14T22:09:57.639Z","repository":{"id":19834639,"uuid":"85901727","full_name":"sudo-suhas/elastic-builder","owner":"sudo-suhas","description":"A Node.js implementation of the elasticsearch Query DSL  :construction_worker:","archived":false,"fork":false,"pushed_at":"2025-01-05T12:05:34.000Z","size":4851,"stargazers_count":517,"open_issues_count":21,"forks_count":78,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-05-11T11:46:17.243Z","etag":null,"topics":["elasticsearch","elasticsearch-query-dsl","javascript","nodejs","query-builder"],"latest_commit_sha":null,"homepage":"https://elastic-builder.js.org","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sudo-suhas.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":"roadmap.md","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2017-03-23T03:14:07.000Z","updated_at":"2025-05-06T14:54:04.000Z","dependencies_parsed_at":"2022-08-07T09:15:40.221Z","dependency_job_id":"b186ac2b-b384-449a-820d-b475c9859396","html_url":"https://github.com/sudo-suhas/elastic-builder","commit_stats":{"total_commits":385,"total_committers":42,"mean_commits":9.166666666666666,"dds":"0.24935064935064932","last_synced_commit":"78de1797fd192fd781bcd67fc0c0b9818479d3a3"},"previous_names":[],"tags_count":80,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sudo-suhas%2Felastic-builder","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sudo-suhas%2Felastic-builder/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sudo-suhas%2Felastic-builder/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sudo-suhas%2Felastic-builder/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sudo-suhas","download_url":"https://codeload.github.com/sudo-suhas/elastic-builder/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254235701,"owners_count":22036964,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["elasticsearch","elasticsearch-query-dsl","javascript","nodejs","query-builder"],"created_at":"2024-08-03T19:00:16.721Z","updated_at":"2025-05-14T22:09:52.620Z","avatar_url":"https://github.com/sudo-suhas.png","language":"JavaScript","readme":"# elastic-builder\n\n[![npm version][version-badge]][package] [![Build Status][build-badge]][build]\n[![Coverage Status][coverage-badge]][coverage]\n[![semantic-release][semantic-release-badge]][semantic-release]\n\nA Node.js implementation of the [Elasticsearch][elasticsearch] DSL for use with\nthe [official elasticsearch javascript client][es-js-client] with builder\nsyntax.\n\n![elastic-builder](elastic-builder.png)\n\n**Check out the [API reference documentation][api-docs].**\n\nRelevant blog post:\nhttps://blog.logrocket.com/elasticsearch-query-body-builder-node-js/\n\nelastic-builder includes TypeScript definition for superior development\nexperience.\n\n## Elasticsearch compatibility\n\n`elastic-builder` was built for 5.x query DSL. However, the library should be\nusable with 2.x as well. For older versions of the DSL, you can try\n[`elastic.js`][elastic-js-fork] or [`bodybuilder`][bodybuilder]\n\n`elastic-builder` is also compatible with elasticsearch 6.0(alpha) for the most\npart. However, there are some [breaking changes][es-6-breaking-changes] which\nhave been called out in the docs(ex: [`Script.file`][api-docs-script-file].\n\nWhat's Included:\n\n- [Request Body Search][es-search-request-body]\n- [Queries][es-query-dsl]\n- [Aggregations][es-search-aggregations]\n- [Suggesters][es-search-suggesters]\n- [Search Template][es-search-template.html]\n\n## Install\n\n```\nnpm install elastic-builder --save\n```\n\n## Usage\n\n```js\nconst esb = require('elastic-builder'); // the builder\n\nconst requestBody = esb.requestBodySearch()\n  .query(esb.matchQuery('message', 'this is a test'));\n\n// OR\n\nconst requestBody = new esb.RequestBodySearch().query(\n  new esb.MatchQuery('message', 'this is a test')\n);\n\nrequestBody.toJSON(); // or print to console - esb.prettyPrint(requestBody)\n{\n  \"query\": {\n    \"match\": {\n      \"message\": \"this is a test\"\n    }\n  }\n}\n```\n\nFor each class, `MyClass`, a utility function `myClass` has been provided which\nconstructs the object for us without the need for `new` keyword.\n\n## REPL\n\nTry it out on the command line using the node REPL:\n\n```\n# Start the repl\nnode ./node_modules/elastic-builder/repl.js\n# The builder is available in the context variable esb\nelastic-builder \u003e esb.prettyPrint(\n...   esb.requestBodySearch()\n...     .query(esb.matchQuery('message', 'this is a test'))\n... );\n{\n  \"query\": {\n    \"match\": {\n      \"message\": \"this is a test\"\n    }\n  }\n}\n```\n\n## Motivation\n\nElasticsearch only provides a low level client for making requests.\n[`elastic.js`][elastic-js] was a relatively popular library for building the\nrequest search body. However, this project is not being maintained nor is the\n[fork][elastic-js-fork]. There were [several changes][es-5-breaking-changes] in\nthe 5.0 release which make the older libraries unusable.\n\nThis library is a port of `elastic.js` to es6 with elasticsearch 5.x\ncompatibility.\n\n## API Reference\n\nAPI reference can be accessed here - https://elastic-builder.js.org/docs. The\ndocs include examples ported from the [official elasticsearch\nreference][es-reference].\n\nAPI documentation was generated using [documentation.js][documentation-js]. It\nis being hosted with help from this awesome project -\nhttps://github.com/js-org/dns.js.org\n\n## Recipes\n\nThe library has a few helper recipes:\n\n- [Missing query][es-missing-query]\n- [Random sort query][es-random-score-query]\n- [Filter query][es-filter-query]\n\n```js\nconst qry = esb.cookMissingQuery('user');\n\nqry.toJSON();\n{\n  \"bool\": {\n    \"must_not\": {\n      \"exists\": { \"field\": \"user\" }\n    }\n  }\n}\n```\n\nCheck out the [reference docs][api-docs-recipes] for more examples.\n\nIf you have any recipes, please do share or better yet, create a [pull\nrequest][create-pull-request] :smile:.\n\n## Changelog\n\n[releases][releases]\n\n## Examples\n\n**Usage with official elasticsearch client:**\n\n```js\n'use strict';\n\nconst elasticsearch = require('elasticsearch');\nconst esb = require('elastic-builder');\n\nconst client = new elasticsearch.Client({\n  host: 'localhost:9200',\n  log: 'trace'\n});\n\nconst requestBody = esb\n  .requestBodySearch()\n  .query(esb.matchQuery('body', 'elasticsearch'));\n\nclient\n  .search({\n    index: 'twitter',\n    type: 'tweets',\n    body: requestBody.toJSON()\n  })\n  .then(resp =\u003e {\n    const hits = resp.hits.hits;\n  })\n  .catch(err =\u003e {\n    console.trace(err.message);\n  });\n```\n\n```js\n// Bool query\nconst requestBody = esb.requestBodySearch().query(\n  esb.boolQuery()\n    .must(esb.matchQuery('last_name', 'smith'))\n    .filter(esb.rangeQuery('age').gt(30))\n);\nrequestBody.toJSON();\n{\n  \"query\": {\n    \"bool\": {\n      \"must\": {\n        \"match\": { \"last_name\": \"smith\" }\n      },\n      \"filter\": {\n        \"range\": { \"age\": { \"gt\": 30 } }\n      }\n    }\n  }\n}\n\n// Multi Match Query\nconst requestBody = esb.requestBodySearch().query(\n  esb.multiMatchQuery(['title', 'body'], 'Quick brown fox')\n    .type('best_fields')\n    .tieBreaker(0.3)\n    .minimumShouldMatch('30%')\n);\nrequestBody.toJSON();\n{\n  \"multi_match\": {\n    \"query\": \"Quick brown fox\",\n    \"type\": \"best_fields\",\n    \"fields\": [\"title\", \"body\"],\n    \"tie_breaker\": 0.3,\n    \"minimum_should_match\": \"30%\"\n  }\n}\n\n// Aggregation\nconst requestBody = esb.requestBodySearch()\n  .size(0)\n  .agg(esb.termsAggregation('popular_colors', 'color'));\nrequestBody.toJSON();\n{\n  \"size\": 0,\n  \"aggs\": {\n    \"popular_colors\": {\n      \"terms\": { \"field\": \"color\" }\n    }\n  }\n}\n\n// Nested Aggregation\nconst requestBody = esb.requestBodySearch()\n  .size(0)\n  .agg(\n    esb.termsAggregation('colors', 'color')\n      .agg(esb.avgAggregation('avg_price', 'price'))\n      .agg(esb.termsAggregation('make', 'make'))\n  );\nrequestBody.toJSON();\n{\n  \"size\": 0,\n  \"aggs\": {\n    \"colors\": {\n      \"terms\": { \"field\": \"color\" },\n      \"aggs\": {\n        \"avg_price\": {\n          \"avg\": { \"field\": \"price\" }\n        },\n        \"make\": {\n          \"terms\": { \"field\": \"make\" }\n        }\n      }\n    }\n  }\n}\n\n// If you prefer using the `new` keyword\nconst agg = new esb.TermsAggregation('countries', 'artist.country')\n  .order('rock\u003eplayback_stats.avg', 'desc')\n  .agg(\n    new esb.FilterAggregation('rock', new esb.TermQuery('genre', 'rock')).agg(\n      new esb.StatsAggregation('playback_stats', 'play_count')\n    )\n  );\nagg.toJSON();\n{\n  \"countries\": {\n    \"terms\": {\n      \"field\": \"artist.country\",\n      \"order\": { \"rock\u003eplayback_stats.avg\": \"desc\" }\n    },\n    \"aggs\": {\n      \"rock\": {\n        \"filter\": {\n          \"term\": { \"genre\": \"rock\" }\n        },\n        \"aggs\": {\n          \"playback_stats\": {\n            \"stats\": { \"field\": \"play_count\" }\n          }\n        }\n      }\n    }\n  }\n}\n\n// Sort\nconst requestBody = esb.requestBodySearch()\n  .query(esb.boolQuery().filter(esb.termQuery('message', 'test')))\n  .sort(esb.sort('timestamp', 'desc'))\n  .sorts([\n    esb.sort('channel', 'desc'),\n    esb.sort('categories', 'desc'),\n    // The order defaults to desc when sorting on the _score,\n    // and defaults to asc when sorting on anything else.\n    esb.sort('content'),\n    esb.sort('price').order('desc').mode('avg')\n  ]);\nrequestBody.toJSON();\n{\n  \"query\": {\n    \"bool\": {\n      \"filter\": {\n        \"term\": { \"message\": \"test\" }\n      }\n    }\n  },\n  \"sort\": [\n    { \"timestamp\": { \"order\": \"desc\" } },\n    { \"channel\": { \"order\": \"desc\" } },\n    { \"categories\": { \"order\": \"desc\" } },\n    \"content\",\n    { \"price\": { \"order\": \"desc\", \"mode\": \"avg\" } }\n  ]\n}\n\n// From / size\nconst requestBody = esb.requestBodySearch()\n  .query(esb.matchAllQuery())\n  .size(5)\n  .from(10);\nrequestBody.toJSON();\n{\n  \"query\": { \"match_all\": {} },\n  \"size\": 5,\n  \"from\": 10\n}\n```\n\nFor more examples, check out the [reference docs][api-docs].\n\n## Validation\n\n`elastic-builder` provides lightweight validation where ever possible:\n\n```\n$ node ./node_modules/elastic-builder/repl.js\nelastic-builder \u003e esb.multiMatchQuery().field('title').field('body').query('Quick brown fox').type('bwst_fields')\nSee https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-multi-match-query.html\nGot 'type' - bwst_fields\nError: The 'type' parameter should belong to Set {\n  'best_fields',\n  'most_fields',\n  'cross_fields',\n  'phrase',\n  'phrase_prefix' }\n    at MultiMatchQuery.type (E:\\Projects\\repos\\elastic-builder\\lib\\queries\\full-text-queries\\multi-match-query.js:134:23)\n    at repl:1:77\n    at ContextifyScript.Script.runInContext (vm.js:35:29)\n    at REPLServer.defaultEval (repl.js:342:29)\n    at bound (domain.js:280:14)\n    at REPLServer.runBound [as eval] (domain.js:293:12)\n    at REPLServer.\u003canonymous\u003e (repl.js:538:10)\n    at emitOne (events.js:96:13)\n    at REPLServer.emit (events.js:188:7)\n    at REPLServer.Interface._onLine (readline.js:239:10)\n```\n\n## Tests\n\nRun unit tests:\n\n```\nnpm test\n```\n\n## Credits\n\n`elastic-builder` is heavily inspired by [`elastic.js`][elastic-js] and the\n[fork][elastic-js-fork] by Erwan Pigneul.\n\n[`bodybuilder`][bodybuilder] for documentation style, build setup, demo page.\n\n## License\n\nMIT © [Suhas Karanth][sudo-suhas]\n\n[version-badge]: https://badge.fury.io/js/elastic-builder.svg\n[package]: https://www.npmjs.com/package/elastic-builder\n[build-badge]:\n  https://github.com/sudo-suhas/elastic-builder/actions/workflows/build.yml/badge.svg\n[build]: https://github.com/sudo-suhas/elastic-builder/actions/workflows/build.yml\n[coverage-badge]:\n  https://coveralls.io/repos/github/sudo-suhas/elastic-builder/badge.svg?branch=master\n[coverage]: https://coveralls.io/github/sudo-suhas/elastic-builder?branch=master\n[semantic-release-badge]:\n  https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg\n[semantic-release]: https://github.com/semantic-release/semantic-release\n[elasticsearch]: https://www.elasticsearch.org/\n[es-js-client]:\n  https://www.elasticsearch.org/guide/en/elasticsearch/client/javascript-api/current/index.html\n[es-reference]:\n  https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html\n[es-5-breaking-changes]:\n  https://www.elastic.co/guide/en/elasticsearch/reference/current/breaking_50_search_changes.html\n[es-6-breaking-changes]:\n  https://www.elastic.co/guide/en/elasticsearch/reference/master/breaking_60_search_changes.html\n[es-search-request-body]:\n  https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-body.html\n[es-query-dsl]:\n  https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl.html\n[es-missing-query]:\n  https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-exists-query.html#_literal_missing_literal_query\n[es-random-score-query]:\n  https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-function-score-query.html#function-random\n[es-filter-query]:\n  https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-bool-query.html\n[es-search-aggregations]:\n  https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations.html\n[es-search-suggesters]:\n  https://www.elastic.co/guide/en/elasticsearch/reference/current/search-suggesters.html\n[es-search-template.html]:\n  https://www.elastic.co/guide/en/elasticsearch/reference/current/search-template.html\n[api-docs]: https://elastic-builder.js.org/docs\n[api-docs-recipes]: https://elastic-builder.js.org/docs#recipes\n[api-docs-script-file]: https://elastic-builder.js.org/docs/#scriptfile\n[releases]: https://github.com/sudo-suhas/elastic-builder/releases\n[elastic-js]: https://github.com/fullscale/elastic.js\n[elastic-js-fork]: https://github.com/ErwanPigneul/elastic.js\n[bodybuilder]: https://github.com/danpaz/bodybuilder\n[documentation-js]: https://github.com/documentationjs/documentation\n[create-pull-request]:\n  https://help.github.com/articles/creating-a-pull-request-from-a-fork/\n[sudo-suhas]: https://github.com/sudo-suhas\n","funding_links":[],"categories":["Elasticsearch developer tools and utilities","JavaScript"],"sub_categories":["Development and debugging"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsudo-suhas%2Felastic-builder","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsudo-suhas%2Felastic-builder","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsudo-suhas%2Felastic-builder/lists"}