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

mongoose-fuzzy-search

v0.0.4

Published

fuzzy search based on trigrams for mongoose odm

Downloads

12,448

Readme

mongoose-fuzzy-search

Mongoose plugin which adds fuzzy search capabilities on a Model based on trigrams sequence similarity

Usage

installation

npm i --save mongoose-fuzzy-search

Apply to a model

import fuzzy from 'mongoose-fuzzy-search';

const schema = new mongoose.Schema('User', {
    firstname: String,
    lastname: String
});

// add the plugin to the model and specify new fields on your schema to hold the trigrams projected 
schema.plugin(fuzzy, {
   fields:{
       lastname_tg: 'lastname', // equivalent to (doc) => doc.get('lastname')
       fullname_tg: (doc) => [doc.get('firstname'), doc.get('lastname') ].join(' ') 
   }
})
const User = mongoose.model('User', schema);

const user = new User({
    firstname: 'Laurent',    
    lastname: 'Renard',    
})


await user.save();

The saved document will be:

{
    "firstname": "Laurent",    
    "lastname": "Renard",
    "lastname_tg":["  r"," re","ren","ena","nar","ard","rd ","d  "],      
    "fullname_tg":["  l"," la","lau","aur","ure","ren","ent","nt ","t  ","  r"," re","ren","ena","nar","ard","rd ","d  "]      
}

Note: when using a string, it is equivalent to a function returning the value of the document at the matching path.

Search

The fuzzy static method returns a Aggregate matching the documents which have at least one matching trigram with the query and their similarity score. You can then decide to extend the pipeline: filter out, sort them, etc

const result = await User.fuzzy('renart') // (.sort(), etc)
// > [{ document: <the document>, similiarity: <the similarity score> }]

similarity score

The similarity score is calculated by dividing the size of the intersection set between the query and the document field trigrams, and the size of the trigrams set for the query.

change the weight of the different fields

When passing a string, the pipeline calculate the similarity for each trigram field and return the mean. However, you can combine various queries and give different weights to each of them:

const results = await User.fuzzy({
            lastname_tg: {
                searchQuery: 'Renard' 
            },
            fullname_tg: {
                searchQuery: 'repnge',
                weight: 20
            }
});

Notes

This plugin does not:

  • add any index: it is up to you
  • remove stop words (which are usually language specific): you can still transform an argument before you pass it to the trigram function using the field options

This plugin does:

  • add Document middleware on save and insertMany middleware in order to update the trigram fields on your documents on insert/update.
  • lowercase, deburr, split in words and concat each word trigram into a unique set

This plugin is adapted for searches when relative strings length difference does not matter much (ideal for short string like emails, names, titles, etc), when the strings have no or very little semantic (like names etc).
Otherwise, you might consider using another solution such as the native mongodb text index or a different database