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

@jayalfredprufrock/mongoes

v0.4.9

Published

Meet the tiny and tasty TypeScript library for best-effort conversion of MongoDB search queries into equivalent ElasticSearch queries. Supports most queries that make sense within the context of ES and also provides support for custom operations. Zero dep

Downloads

666

Readme

MongoES

Meet the tiny and tasty TypeScript library for best-effort conversion of MongoDB search queries into equivalent ElasticSearch queries. Supports most queries that make sense within the context of ES and also provides support for custom operations. Zero dependencies.

npm i @jayalfredprufrock/mongoes

Usage

import { convertQuery } from 'mongoes';

const query = convertQuery({
    $and: [
        { type: 'fruit' },
        {
            $or: [{ name: 'mango' }, { name: 'el mango' }],
        },
    ],
});

// query
// {
//    bool: {
//        must: [
//            { term: { type: 'fruit' } },
//            {
//                bool: {
//                    should: [
//                          { term: { name: 'mango' } },
//                          { term: { name: 'el mango' } }
//                    ],
//                    minimum_should_match: 1
//                },
//            },
//        ],
//    },
// }

Built-in Operators

See MongoDb docs for a list of operators and options. Also check out the sift.js library, which provides support for evaluating/filtering in-memory objects using this same mongo-style syntax. A major motiviation for MongoES was to have a single filtering/querying syntax that could be used both against ES indexes and in-memory objects.

Custom Operators

OOTB, mongoes includes a few operators that aren't a part of the MongoDB query specification:

  • $like - Maps to ES Wildcard queries. Both * and % can be used to match zero or more characters, while ? can be used to match exactly one character. Like the $regex operator, set $options to "i" to set the ES option case_insensitive to true. Note that exactly how ElasticSearch treats case sensitivity is also dependent on the underlying field mapping.
  • $prefix - Maps to ES Prefix queries. Similar to $like, supports passing "i" to $options for case insensitivity.
  • $ids - Maps to ES "ids" query. The operand is an array of document _ids. The field name is not used when constructing the ES query, however it is used to specify a document-level id field for supporting Sift queries.
  • $empty - Works just like $exists, but does not consider empty strings (after trimming) to exist.

Additionally, users can create their own custom operations by including an object of operator functions:

const operators = {
    $fuzz: (field: string, operand: string, options?: { fuzziness?: number | 'AUTO' }) => {
        return { fuzzy: { [field]: { value: operand, ...options } } };
    },
};

const query = convertQuery({ name: { $fuzz: 'Mangeos', $options: { fuzziness: 2 } } }, { operators });

// query
// {
//    bool: {
//        must: {
//            fuzzy: {
//                name: {
//                    value: 'Mangeos',
//                    fuzziness: 2
//                }
//            }
//        }
//    }
//}

Gotchas

  • Assumes valid mongodb queries. No guarantees about what is returned/thrown for invalid mongodb queries. Please create an issue if there is specific invalid syntax that you think should be handled differently at runtime.
  • Uses term queries for all text related operators. Might provide support for "match" queries if there is interest.
  • Not all operators translate cleanly to ES. The following operators are unsupported: $where, $type, $size, $mod
  • $elemMatch translates to a nested query
  • $or queries always translate into should + minimum_should_match=1. This allows adjacent $and operators (including implicit) to work as expected.
  • $all operator within $elemMatch is converted to must + multiple term expressions.
  • No guarantee about the syntactical stability of queries to allow future optimizations without a major version bump
  • Some attempt made to produce compact representations: e.g. removes redundant { bool: { must: { bool: exp }}}
  • Queries involving regular expressions or wildcards (i.e. $regex, $like, $prefix, etc. ) should be used sparingly since they are significantly more expensive than simpler query operators.
  • Lucene's regex engine (mostly PCRE) is not fully compatible with JavaScript's. Of particular note:
    • only support for i flag (case insensitive)
    • no support for ^ and $ (start/end anchors)