npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

elastic-aggs

v7.0.0-prerelease-3

Published

Typescript definitions for type-safe Elasticsearch aggregations

Downloads

11

Readme

elastic-aggs

Typescript definitions for type-safe Elasticsearch aggregations

Installation

npm install elastic-aggs

How to use type-safe aggregations

Simply replace import for the Elasticsearch Client interface:

import { Client } from 'elastic-aggs';

The Client interface provided is itself based on the (peer) Elasticsearch dependancy, but with an additional function prototype for search that implements strongly typed aggregation specifications and results.

To use the types, you must as a Doc member to the search parameter that specifies what is stored in your ES index. If you don't have a Doc member, you're using the standard, Elasticsearch search definition.

Example

https://user-images.githubusercontent.com/2789075/232029391-fbf8f785-1c1b-4113-9d69-5c040f135c52.mp4

In the example, we first add a Doc member that specifes the type of the documents stored in the Elasticsearch index. This triggers the additional function prototype, which then complains because there is no aggs member.

As the aggs are entered, we're prompted for field values based on the fields in the Doc. This includes nested field member.

When handling the result, the aggregations have named, typed members, including nested aggregation results, quickly catching typos and incorrect aggregations.

What's up Doc?

The Doc member is not used as run-time. It is only used to carry the type in the additional search function prototype. To avoid issues with the Elasticsearch library, it should evalue to undefined. A constant SourceDoc = undefined as unknown is exported so you can easily type-cast your document type.

const result = await es.search({
    Doc: SourceDoc as SomeArbitraryTypeOfTheDocs
    ...
});

Additionally, the constant AnyDoc is exported if you only want the aggregation result resolution and don't require field-level results.

Why is it a member and not a type parameter?

Typescript does not handle default type parameters (or variable type parameter lists) appropriately for this kind of call. It needs to capture not only the Doc but the exact, const (Readonly) type of the search parameter in order to be able to resolve the aggregations fully. Specifying it as an unused (undefined) parameter makes this possible.

Status

At present, only a limited number of aggregations are provided (see LeafAggregationKeys and NodeAggregationKeys in https://github.com/MatAtBread/elastic-aggs/blob/main/typed-aggregations.ts#L122).

The same techniques can be used to implement many more and PRs to do so are welcome.

It doesn't work!

It does, but it requires that strings in particular are const or Readonly. This is becuase by default Typescript expands type defintions of string constants to string:

    e = 'abc' // e is of type string
    f = 'abc' as const; // f is of type "abc"

The function prototype will capture this in many cases, but if your aggregation is the result of a function call, or other expression where a constant string type is assigned to a mutable or conditional, the "constant" attribute will be lost. Use Readonly<...> or DeepReadonly<...> as the return type of such functions to avoid Typescript's native behaviour.