Socket
Socket
Sign inDemoInstall

elasticmagic

Package Overview
Dependencies
Maintainers
1
Versions
5
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

elasticmagic

JS orm for elasticsearch.


Version published
Weekly downloads
5
increased by150%
Maintainers
1
Weekly downloads
 
Created
Source

elasticmagic-js (alpha)

This is alpha. Api may/will change.

JS/Typescript DSL for Elasticsearch

This lib is a port of original library written in python by @anti-social

Supports Elasticsearch version 6.x

Getting Started

Install elasticmagic-js using npm:

npm install elasticmagic

Examples

Let's get started by writing a simple query.

  1. Declare class. We will use it both as query builder and container for data from elastic.

    As you can see we declare one static field and one intance field with almost same name but different types.
    Static field will be used to build queries. Instance field will be populated on search query so they must be the same as in elasticsearch document.

import { Client } from '@elastic/elasticsearch';
import { 
  Cluster,
  Field,
  IntegerType,
  Doc,
  Bool,
} from "elasticmagic-js";

enum OrderStatus {
  new = 1,
  paid = 2,
  handled = 3,
  canceled = 4,
}

enum OrderSource {
  desktop = 1,
  mobile = 2,
}

class OrderDoc extends Doc {
  public static docType: string = 'order';

  public static userId = new Field(DateType, 'user_id', OrderDoc);
  public user_id?: number;

  public static status = new Field(DateType, 'status', OrderDoc);
  public status?: number;

  public static source = new Field(DateType, 'source', OrderDoc);
  public source?: number;

  public static price = new Field(DateType, 'price', OrderDoc);
  public price?: number;

  public static dateCreated = new Field(DateType, 'date_created', OrderDoc);
  public date_created?: Date;
}
  1. Create elasticsearch client and pass it to Cluester
const client = new Client({ node: 'http://es6-test:9200' });
const cluster = new Cluster(client, 'test_order_index');

  1. Now we ready to write our query
const query = cluster.searchQuery({ routing: 1 })
  .source(false)
  .filter(
    Bool.must(
      OrderDoc.user_id.in([1]),
      OrderDoc.status.in([OrderStatus.new, OrderStatus.paid]),
      OrderDoc.source.not(OrderSource.mobile),
    )
  )
  .limit(0);

console.log(query.toJSON()) // or console.log(query.body)

It will print:

{
  query: {
    bool: {
      filter: {
        bool: {
          must: [
            {terms: {user_id: [1]}},
            {terms: {status: [1, 2]}},
            {bool: {
              must_not: [
                {term: {source: 2}}
              ]
            }}
          ]
        }
      }
    }
  },
  _source: false,
  size: 0
}
  1. To fetch results from elasticsearch: Lets suppouse we have one doc in index with id 1.
const result = await query.getResult<OrderDoc>();
console.log(result.getIds()); // prints [1]
const hit = result.hits[0];

console.log(hit.user_id); // prints 1
Aggregations
const query = searchQuery
  .source(false)
  .filter(
    Bool.must(
      OrderDoc.userId.in([1]),
      OrderDoc.status.in([OrderStatus.new, OrderStatus.handled, OrderStatus.paid]),
      OrderDoc.source.not(OrderSource.mobile),
      OrderDoc.dateCreated.lte(new Date().toISOString()),
    )
  )
  .aggregations({
    usersOrders: new agg.Terms({
      field: OrderDoc.userId,
      size: 1,
      aggs: {
        total: new agg.Filter({
          filter: OrderDoc.conditionSourceDesktop(),
          aggs: {
            selled: new agg.Filter({
              filter: Bool.must(
                OrderDoc.status.in([OrderStatus.paid, OrderStatus.handled]),
              ),
              aggs: {
                paid: new agg.Filter({
                  filter: OrderDoc.status.eq(OrderStatus.paid)
                }), 
                handled: new agg.Filter({
                  filter: OrderDoc.status.eq(OrderStatus.handled)
                }),
              }
            }),
            canceled: new agg.Filter({
              filter: OrderDoc.status.eq(OrderStatus.canceled),
            }),
            new: new agg.Filter({
              filter: OrderDoc.status.eq(OrderStatus.new)
            })
          }
        }),
        lowcost: new agg.Filter({
          filter: OrderDoc.conditionLowPrice()
        })
      }
    })
  });

Now you can get aggregation data


const result = await query.getResult<OrderDoc>();

const usersOrders = result.getAggregation("usersOrders");
console.log(usersOrders.buckets[0].key) // prints 1
console.log(usersOrders.buckets[0].docCount) // prints 1

const total = usersOrders.buckets[0].getAggregation("total")
console.log(total.docCount) // prints 1

Development

Tests

Run all tests

make test

Run one test

make test TEST=tests/testSearchQuery.spec.ts
# or
make test TEST=testSearchQuery.spec.ts

TODO

  • documentation (https://typedoc.org, docusaurus, js.org)
  • add support for elasticsearch 5, 7 versions, compilers for different es versions
  • precommit hooks
  • generate doc with jsDoc
  • generate doc like ttag has
  • elasticsearch must be devDep or peerDep, but not production dep (create Client interface)
  • scroll
  • pagination
  • queryFilters
  • function_score, inline functions
  • sub documents
  • more tests
  • indexing, delete, bulk (CRUD)
  • post_filters
  • rescores
  • highlight
  • add doc to methods
  • MultiMatch, Ids
  • api docs

Keywords

FAQs

Package last updated on 09 Jan 2020

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc