{"id":24054336,"url":"https://github.com/kindermax/elasticmagic-js","last_synced_at":"2026-01-28T21:00:57.649Z","repository":{"id":40895558,"uuid":"231576107","full_name":"kindermax/elasticmagic-js","owner":"kindermax","description":"JS/Typescript DSL for Elasticsearch","archived":false,"fork":false,"pushed_at":"2023-01-05T04:57:47.000Z","size":1102,"stargazers_count":22,"open_issues_count":9,"forks_count":2,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-26T07:13:56.504Z","etag":null,"topics":["aggregations","builder","dsl","elasticsearch","orm","typescript","typescript-dsl"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kindermax.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-01-03T11:43:30.000Z","updated_at":"2025-08-18T02:26:55.000Z","dependencies_parsed_at":"2023-02-03T11:15:51.563Z","dependency_job_id":null,"html_url":"https://github.com/kindermax/elasticmagic-js","commit_stats":null,"previous_names":["kindritskyimax/elasticmagic-js"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/kindermax/elasticmagic-js","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kindermax%2Felasticmagic-js","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kindermax%2Felasticmagic-js/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kindermax%2Felasticmagic-js/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kindermax%2Felasticmagic-js/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kindermax","download_url":"https://codeload.github.com/kindermax/elasticmagic-js/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kindermax%2Felasticmagic-js/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28851838,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-28T15:15:36.453Z","status":"ssl_error","status_checked_at":"2026-01-28T15:15:13.020Z","response_time":57,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["aggregations","builder","dsl","elasticsearch","orm","typescript","typescript-dsl"],"created_at":"2025-01-09T03:04:30.849Z","updated_at":"2026-01-28T21:00:57.618Z","avatar_url":"https://github.com/kindermax.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"elasticmagic-js - JS/Typescript DSL for Elasticsearch\n=======================\n\n\u003e The project is still very much a work in progress and in an alpha state, api may/will change; input and contributions welcome!\n\n[![actions](https://github.com/kindritskyiMax/elasticmagic-js/workflows/tests/badge.svg?branch=master)](https://github.com/kindritskyiMax/elasticmagic-js/actions)\n\nElasticmagic is an Elasticsearch query builder and ORM for JavaScript/Typescript.\n\nIt helps you easily build queries which are typed and safe. \n\nYou do not need to remember how to write `json` DSL for Elasticsearch, Elasticmagic will do it for you.\n\n\n\u003e This lib is a port of original library written in `python` by [@anti-social]( https://github.com/anti-social/elasticmagic )\n\n## Versions\n\nSupports Elasticsearch version 6.x\n\n## Docs\n\n**Docs** - [https://elasticmagic.js.org/](https://elasticmagic.js.org/)\n\n**Changelog** - [https://elasticmagic.js.org/docs/changelog](https://elasticmagic.js.org/docs/changelog)\n\n## Installation\n\nTo install Elasticmagic via NPM:\n\n```bash\nnpm install --save elasticmagic\n```\n\nAlso you need an Elasticseach official js client\n\n```bash\nnpm install --save @elastic/elasticsearch\n```\n\n## Getting Started\n\n#### Query building\n\n```javascript\nimport { Client } from '@elastic/elasticsearch';\nimport { \n  Cluster,\n  Field,\n  IntegerType,\n  Doc,\n  Bool,\n} from \"elasticmagic-js\";\n\n\n/**\n * Here we creating our document which maps structure of same document in Elasticsearch.  \n * \n * We will use this class as our query builder.\n * Also when we will get result from elasticsearch, we instantiate this class\n * and populate it with data from Elasticsearch hits.\n * \n * First we declare docType - it must be the same as document in Elasticsearch mapping. \n * \n * Then we declare static fields that will be user to build our queries. \n * As we do not need an instance of this class to build queries, the fields are static.\n * \n * Next, conventionaly, we declare instance properties, as you can see, with almost same name. \n * Then lettercase is same as fields in Elasticseach mapping\n * \n * And thats is.  \n */\nclass OrderDoc extends Doc {\n  public static docType: string = 'order';\n\n  public static userId = new Field(IntegerType, 'user_id', OrderDoc);\n  public user_id?: number;\n\n  public static status = new Field(IntegerType, 'status', OrderDoc);\n  public status?: number;\n\n  public static source = new Field(IntegerType, 'source', OrderDoc);\n  public source?: number;\n\n  public static price = new Field(IntegerType, 'price', OrderDoc);\n  public price?: number;\n\n  public static dateCreated = new Field(DateType, 'date_created', OrderDoc);\n  public date_created?: Date;\n}\n\n// Create a Elasticsearch client which will be passed to cluster.\nconst client = new Client({ node: 'http://es6-test:9200' });\n// Create cluster instance. Its an entrypiint for interacting with Elasticsearch.\nconst cluster = new Cluster(client, 'test_order_index');\n\n\n// Lets start building our query.\n// Calling searchQuery method we start creating new query.\n// We using builder pattern, so you can chain any amount of methods\nconst query = cluster.searchQuery({ routing: 1 })\n  .source(true)\n  .filter(\n    Bool.must(\n      OrderDoc.userId.in([1]),\n      OrderDoc.status.in([1, 2]),\n      OrderDoc.source.not(1),\n      OrderDoc.dateCreated.lte(new Date().toISOString())\n    )\n  );\n\n// To make a query to Elasticsearch we calling getResult.\nconst result = await query.getResult\u003cOrderDoc\u003e();\nconsole.log(result.getIds()); // prints [\"1\"]\n\nconst hit = result.hits[0];\nconsole.log(hit.user_id); // prints 1\n```\n\nWe can check what query Elasticmagic will build for us.\n\n```javascript\nconsole.log(query.toJSON()) \n// to see prettified query\nconsole.log(query.toPrettyJSON());\n```\n\n#### Aggregations\n\n```javascript\nconst query = searchQuery\n  .source(false)\n  .filter(\n    Bool.must(\n      OrderDoc.userId.in([1]),\n      OrderDoc.status.in([OrderStatus.new, OrderStatus.handled, OrderStatus.paid]),\n      OrderDoc.source.not(OrderSource.mobile),\n      OrderDoc.dateCreated.lte(new Date().toISOString()),\n    )\n  )\n  .aggregations({\n    usersOrders: new agg.Terms({\n      field: OrderDoc.userId,\n      size: 1,\n      aggs: {\n        total: new agg.Filter({\n          filter: OrderDoc.conditionSourceDesktop(),\n          aggs: {\n            selled: new agg.Filter({\n              filter: Bool.must(\n                OrderDoc.status.in([OrderStatus.paid, OrderStatus.handled]),\n              ),\n              aggs: {\n                paid: new agg.Filter({\n                  filter: OrderDoc.status.eq(OrderStatus.paid)\n                }), \n                handled: new agg.Filter({\n                  filter: OrderDoc.status.eq(OrderStatus.handled)\n                }),\n              }\n            }),\n            canceled: new agg.Filter({\n              filter: OrderDoc.status.eq(OrderStatus.canceled),\n            }),\n            new: new agg.Filter({\n              filter: OrderDoc.status.eq(OrderStatus.new)\n            })\n          }\n        }),\n        lowcost: new agg.Filter({\n          filter: OrderDoc.conditionLowPrice()\n        })\n      }\n    })\n  });\n```\n\nNow you can get aggregation data\n\n```javascript\n\nconst result = await query.getResult\u003cOrderDoc\u003e();\n\nconst usersOrders = result.getAggregation(\"usersOrders\");\nconsole.log(usersOrders.buckets[0].key) // prints 1\nconsole.log(usersOrders.buckets[0].docCount) // prints 1\n\nconst total = usersOrders.buckets[0].getAggregation(\"total\")\nconsole.log(total.docCount) // prints 1\n```\n\n## Tests\n\nRun all tests\n\n```bash\nmake test\n```\n\nRun one test\n\n```bash\nmake test TEST=tests/testSearchQuery.spec.ts\n# or\nmake test TEST=testSearchQuery.spec.ts\n```\n\n## TODO\n\n#### Document API (CRUD)\n\n- [ ] Index API\n- [ ] Get API\n- [ ] Delete API\n- [ ] Delete By Query API\n- [ ] Update API\n- [ ] Update By Query API\n- [ ] Multi Get API\n- [ ] Bulk API\n- [ ] Reindex API\n  \n#### Query DSL\n- [x] searchQuery\n- [x] aggregations\n- [ ] Match All Query\n- [ ] Match All Query\n- Full text queries\n  - [ ] Match Query\n  - [ ] Match Phrase Query\n  - [ ] Match Phrase PrefixQuery\n  - [ ] Multi Match Query\n  - [ ] Common Terms Query\n  - [ ] Query String Query\n  - [ ] Simple Query String Query\n- Term level queries\n  - [x] Term Query\n  - [x] Terms Query\n  - [ ] Terms Set Query\n  - [x] Range Query\n  - [ ] Exists Query\n  - [ ] Prefix Query\n  - [ ] Wildcard Query\n  - [ ] Regexp Query\n  - [ ] Fuzzy Query\n  - [ ] Type Query\n  - [ ] Ids Query\n- Compound queries\n  - [ ] Constant Score Query\n  - [ ] Bool Query\n  - [ ] Dis Max Query\n  - [ ] Function Score Query\n  - [ ] Boosting Query\n- Joining queries\n  - [ ] Nested Query\n  - [ ] Has Child Query\n  - [ ] Has Parent Query\n  - [ ] Parent Id Query\n- Specialized queries\n  - [ ] Distance Feature Query\n  - [ ] More Like This Query\n  - [ ] Script Query\n  - [ ] Script Score Query\n  - [ ] Percolate Query\n- Sorting\n  - [ ] Sort by score\n  - [x] Sort by field\n  - [ ] Sort by geo distance\n  - [ ] Sort by script\n  - [ ] Sort by doc\n\n  \n#### Search APIs (\n\n- [ ] Multi Search\n- [ ] Search Shards API\n- [ ] Multi Search API\n- [ ] Count API\n- [ ] Validate API\n- [ ] Explain API\n- [ ] Profile API\n\n\n#### Elasticsearch versions interop\n\n- [ ] add support for elasticsearch 5, 7 versions, compilers for different es versions\n\n#### Development\n\n- [ ] precommit hooks\n- [ ] fix integration tests by randomly creating indexes, so tests can be run in parallel\n- [ ] add documentation to methods\n- [ ] generate api docs (typedoc)\n  \n#### cat APIs\n\n#### Other\n\n- [ ] Post filters\n- [ ] Rescores\n- [ ] Scroll\n- [ ] Pagination\n- [ ] QueryFilters\n- [ ] Sub document in field\n- [ ] Sub field in field\n- [ ] Highlight\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkindermax%2Felasticmagic-js","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkindermax%2Felasticmagic-js","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkindermax%2Felasticmagic-js/lists"}