Giter Site home page Giter Site logo

vassilispallas / mongoose-fuzzy-searching Goto Github PK

View Code? Open in Web Editor NEW
129.0 5.0 51.0 751 KB

Mongoose Fuzzy Searching Plugin

Home Page: https://www.npmjs.com/package/mongoose-fuzzy-searching

License: MIT License

JavaScript 97.44% Makefile 2.56%
mongoose fuzzy searching search plugin mongo mongodb

mongoose-fuzzy-searching's Introduction

Mongoose Fuzzy Searching

mongoose-fuzzy-searching is simple and lightweight plugin that enables fuzzy searching in documents in MongoDB. This code is based on this article.

Build Status codecov License: MIT FOSSA Status

Features

Install

Install using npm

$ npm i mongoose-fuzzy-searching

or using yarn

$ yarn add mongoose-fuzzy-searching

Getting started

Initialize plugin

Before starting, for best practices and avoid any issues, handle correctly all the Deprecation Warnings.

In order to let the plugin create the indexes, you need to set useCreateIndex to true. The below example demonstrates how to connect with the database.

const options = {
  useNewUrlParser: true,
  useUnifiedTopology: true,
  useFindAndModify: false,
  useCreateIndex: true,
};

mongoose.Promise = global.Promise;
return mongoose.connect(URL, options);

In the below example, we have a User collection and we want to make fuzzy searching in firstName and lastName.

const { Schema } = require('mongoose');
const mongoose_fuzzy_searching = require('mongoose-fuzzy-searching');

const UserSchema = new Schema({
  firstName: String,
  lastName: String,
  email: String,
  age: Number,
});

UserSchema.plugin(mongoose_fuzzy_searching, { fields: ['firstName', 'lastName'] });
const User = mongoose.model('User', UserSchema);
module.exports = { User };
const user = new User({ firstName: 'Joe', lastName: 'Doe', email: '[email protected]', age: 30 });

try {
  await user.save(); // mongodb: { ..., firstName_fuzzy: [String], lastName_fuzzy: [String] }
  const users = await User.fuzzySearch('jo');

  console.log(users);
  // each user object will not contain the fuzzy keys:
  // Eg.
  // {
  //   "firstName": "Joe",
  //   "lastName": "Doe",
  //   "email": "[email protected]",
  //   "age": 30,
  //   "confidenceScore": 34.3 ($text meta score)
  // }
} catch (e) {
  console.error(e);
}

The results are sorted by the confidenceScore key. You can override this option.

try {
  const users = await User.fuzzySearch('jo').sort({ age: -1 }).exec();
  console.log(users);
} catch (e) {
  console.error(e);
}

Plugin options

Options can contain fields and middlewares.

Fields

Fields attribute is mandatory and should be either an array of Strings or an array of Objects.

String field

If you want to use the default options for all your fields, you can just pass them as a string.

const mongoose_fuzzy_searching = require('mongoose-fuzzy-searching');

const UserSchema = new Schema({
  firstName: String,
  lastName: String,
  email: String,
});

UserSchema.plugin(mongoose_fuzzy_searching, { fields: ['firstName', 'lastName'] });
Object field

In case you want to override any of the default options for your arguments, you can add them as an object and override any of the values you wish. The below table contains the expected keys for this object.

key type default description
name String null Collection key name
minSize Integer 2 N-grams min size. Learn more about N-grams
weight Integer 1 Denotes the significance of the field relative to the other indexed fields in terms of the text search score. Learn more about index weights
prefixOnly Boolean false Only return ngrams from start of word. (It gives more precise results)
escapeSpecialCharacters Boolean true Remove special characters from N-grams.
keys Array[String] null If the type of the collection attribute is Object or [Object] (see example), you can define which attributes will be used for fuzzy searching

Example:

const mongoose_fuzzy_searching = require('mongoose-fuzzy-searching');

const UserSchema = new Schema({
  firstName: String,
  lastName: String,
  email: String,
  content: {
      en: String,
      de: String,
      it: String
  }
  text: [
    {
      title: String,
      description: String,
      language: String,
    },
  ],
});

UserSchema.plugin(mongoose_fuzzy_searching, {
  fields: [
    {
      name: 'firstName',
      minSize: 2,
      weight: 5,
    },
    {
      name: 'lastName',
      minSize: 3,
      prefixOnly: true,
    },
    {
      name: 'email',
      escapeSpecialCharacters: false,
    },
    {
      name: 'content',
      keys: ['en', 'de', 'it'],
    },
    {
      name: 'text',
      keys: ['title', 'language'],
    },
  ],
});

Middlewares

Middlewares is an optional Object that can contain custom pre middlewares. This plugin is using these middlewares in order to create or update the fuzzy elements. That means that if you add pre middlewares, they will never get called since the plugin overrides them. To avoid that problem you can pass your custom midlewares into the plugin. Your middlewares will be called first. The middlewares you can pass are:

  • preSave
    • stands for schema.pre("save", ...)
  • preInsertMany
    • stands for schema.pre("insertMany", ...)
  • preUpdate
    • stands for schema.pre("update", ...)
  • preUpdateOne
    • stands for schema.pre("updateOne", ...)
  • preFindOneAndUpdate
    • stands for schema.pre("findOneAndUpdate", ...)
  • preUpdateMany
    • stands for schema.pre("updateMany", ...)

If you want to add any of the middlewares above, you can add it directly on the plugin.

const mongoose_fuzzy_searching = require('mongoose-fuzzy-searching');

const UserSchema = new Schema({
  firstName: String,
  lastName: String,
});

UserSchema.plugin(mongoose_fuzzy_searching, {
  fields: ['firstName'],
  middlewares: {
    preSave: function () {
      // do something before the object is saved
    },
  },
});

Middlewares can also be asynchronous functions:

const mongoose_fuzzy_searching = require('mongoose-fuzzy-searching');

const UserSchema = new Schema({
  firstName: String,
  lastName: String,
});

UserSchema.plugin(mongoose_fuzzy_searching, {
  fields: ['firstName'],
  middlewares: {
    preUpdateOne: async function {
      // do something before the object is updated (asynchronous)
    }
  }
});

Query parameters

The fuzzy search query can be used either as static function, or as a helper, which let's you to chain multiple queries together. The function name in either case is surprise, surprise, fuzzySearch.

Instance method

Instance method can accept up to three parameters. The first one is the query, which can either be either a String or an Object. This parameter is required. The second parameter can either be eiter an Object that contains any additional queries (e.g. age: { $gt: 18 }), or a callback function. If the second parameter is the queries, then the third parameter is the callback function. If you don't set a callback function, the results will be returned inside a Promise.

The below table contains the expected keys for the first parameter (if is an object)

key type deafult description
query String null String to search
minSize Integer 2 N-grams min size.
prefixOnly Boolean false Only return ngrams from start of word. (It gives more precise results) the prefix
exact Boolean false Matches on a phrase, as opposed to individual terms

Example:

/* With string that returns a Promise */
User.fuzzySearch('jo').then(console.log).catch(console.error);

/* With additional options that returns a Promise */
User.fuzzySearch({ query: 'jo', prefixOnly: true, minSize: 4 })
  .then(console.log)
  .catch(console.error);

/* With additional queries that returns a Promise */
User.fuzzySearch('jo', { age: { $gt: 18 } })
  .then(console.log)
  .catch(console.error);

/* With string and a callback */
User.fuzzySearch('jo', (err, doc) => {
  if (err) {
    console.error(err);
  } else {
    console.log(doc);
  }
});

/* With additional queries and callback */
User.fuzzySearch('jo', { age: { $gt: 18 } }, (err, doc) => {
  if (err) {
    console.error(err);
  } else {
    console.log(doc);
  }
});

Query helper

You can also use the query is a helper function, which is like instance methods but for mongoose queries. Query helper methods let you extend mongoose's chainable query builder API.

Query helper can accept up to two parameters. The first one is the query, which can either be either a String or an Object. This parameter is required. The second parameter can be an Object that contains any additional queries (e.g. age: { $gt: 18 }), which is optional. This helpers doesn't accept a callback function. If you pass a function it will throw an error. More about query helpers.

Example:

const user = await User.find({ age: { $gte: 30 } })
  .fuzzySearch('jo')
  .exec();

Working with pre-existing data

The plugin creates indexes for the selected fields. In the below example the new indexes will be firstName_fuzzy and lastName_fuzzy. Also, each document will have the fields firstName_fuzzy[String] and lastName_fuzzy[String]. These arrays will contain the anagrams for the selected fields.

const mongoose_fuzzy_searching = require('mongoose-fuzzy-searching');

const UserSchema = new Schema({
  firstName: String,
  lastName: String,
  email: String,
  age: Number,
});

UserSchema.plugin(mongoose_fuzzy_searching, { fields: ['firstName', 'lastName'] });

In other words, this plugin creates anagrams when you create or update a document. All the pre-existing documents won't contain these fuzzy arrays, so fuzzySearch function, will not be able to find them.

Update all pre-existing documents with ngrams

In order to create anagrams for pre-existing documents, you should update each document. The below example, updates the firstName attribute to every document on the collection User.

const cursor = Model.find().cursor();
cursor.next(function (error, doc) {
  const obj = attrs.reduce((acc, attr) => ({ ...acc, [attr]: doc[attr] }), {});
  return Model.findByIdAndUpdate(doc._id, obj);
});

Delete old ngrams from all documents

In the previous example, we set firstName and lastName as the fuzzy attributes. If you remove the firstName from the fuzzy fields, the firstName_fuzzy array will not be removed by the collection. If you want to remove the array on each document you have to unset that value.

const cursor = Model.find().cursor();
cursor.next(function (error, doc) {
  const $unset = attrs.reduce((acc, attr) => ({ ...acc, [`${attr}_fuzzy`]: 1 }), {});
  return Model.findByIdAndUpdate(data._id, { $unset }, { new: true, strict: false });
});

Testing and code coverage

All tests

We use jest for all of our unit and integration tests.

$ npm test

Note: this will run all suites serially to avoid mutliple concurrent connection on the db.

This will run the tests using a memory database. If you wish for any reason to run the tests using an actual connection on a mongo instance, add the environment variable MONGO_DB:

$ docker run --name mongo_fuzzy_test -p 27017:27017 -d mongo
$ MONGO_DB=true npm test

Available test suites

unit tests

$ npm run test:unit

Integration tests

$ npm run test:integration

License

MIT License

Copyright (c) 2019 Vassilis Pallas

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

FOSSA Status

mongoose-fuzzy-searching's People

Contributors

aladinflux avatar bswank avatar dbads avatar dependabot[bot] avatar fossabot avatar hommesauvage avatar molteh avatar pong420 avatar vassilispallas avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

mongoose-fuzzy-searching's Issues

Fuzzy Search not working if query is provided

Do you want to request a feature, an issue, or report a bug?
Yes

What is the current behaviour?
If passed something to the query no document is returned, if nothing is passed to the query every post is correctly returned.
Even if the full entry content is provided no document is found

Edit:
I found out that the indexes are appended with _fuzzy, removing them results in correct behaviour but the fields provided for index are removed from the documents found

If the current behaviour is a bug, please provide the steps to reproduce.

What is the expected behaviour?
Returning a document using fuzzy search

If this is a feature request, what is the motivation or use case for changing
the behaviour?

Please mention other relevant information such as Node.js and mongoose version.

"mongoose": "^6.2.10",
"mongoose-fuzzy-searching": "^2.0.2",

Fuzzy fields array are empty.

Hi, this looks like the plugin I need, unfortunately cannot get it working, see Schema below:

const crypto = require('crypto');
const mongoose = require('mongoose');
const mongoose_fuzzy_searching = require('mongoose-fuzzy-searching');

const userSchema = new mongoose.Schema({
  email: { type: String, unique: true },
  password: String,
  passwordResetToken: String,
  passwordResetExpires: Date,
  emailVerificationToken: String,
  emailVerified: Boolean,

  profile: {
    name: String,
    firstName: String,
    secondName: String,
  }
}, { timestamps: true });

userSchema.plugin(mongoose_fuzzy_searching, { fields: ['profile.firstName', 'profile.secondName'] });

I can see firstName_fuzzy and the second field created but both are empty. I deleted old indexes for firstName and secondName.

Should this be populated straight after adding new user or updating one?

update to mongoose 6.x.x

Do you want to request a feature, an issue, or report a bug?
yes
What is the current behaviour?
I can't install it with mongoose 6.x.x normally.
If the current behaviour is a bug, please provide the steps to reproduce.

What is the expected behaviour?
It should have mongoose 6.x.x included in peer dependency
If this is a feature request, what is the motivation or use case for changing
the behaviour?

Please mention other relevant information such as Node.js and mongoose version.
node js 16.13.0
mongoose 6.0.12

Feature Request

As a note , it was difficult to figure out the NGrams had not been built . As a suggestion an error should be returned if the ngrams are not found within the database.

No Error, no Results when setting other searchfields

Hey,
this seems to be more of an implementation problem but anyway:
Using your example code works fine, but when i change the searching-fields to something other than "firstName" or "lastName" i dont get any results and no error.

var mongoose_fuzzy_searching = require('mongoose-fuzzy-searching');
const mongoose = require("mongoose");

var UserSchema = new mongoose.Schema({
    firstName: String,
    lastName: String,
    email: String,
    age: Number,
    jobName: String
});

UserSchema.plugin(mongoose_fuzzy_searching, {fields: ['jobName']});

var User = mongoose.model('fuzUser', UserSchema);

async function testFuzzy(){

    var user = new User({ firstName: 'Joe',  lastName: 'Doe', email: '[email protected]', age: 30, jobName:'carpenter'});
         await user.save(function () {console.log("saved") });
         await User.fuzzySearch('carpenter', function (err, users) {
            console.error(err);
            console.log("users: ", users);
       })
   
}
 testFuzzy();

Output is:

saved
null
users: []

Do you have any idea where my error is ?

Using keys with dynamic object values, does not set fuzzy values

Hi,

I am using another mongoose plugin for multiple languages, so it dynamically creates new field in the name field.
https://www.npmjs.com/package/mongoose-intl plugin for multiple languages

const itemSchema = new Schema({
  name: {
    type: String,
    required: true,
    intl: true,
  },
  description: {
    type: String,
    intl: true,
  },
  base_price: {
    type: Number,
    required: true,
  },
})

itemSchema.plugin(mongooseIntl, { languages: LANGUAGES.split(','), defaultLanguage: 'en' });
itemSchema.plugin(mongoose_fuzzy_searching, 
  { fields: [
    {
      name: 'name',
      keys: LANGUAGES.split(',')
    },
  ]});
const itemModel = mongoose.model('item', itemSchema);

But when i try to create a new document with the name field as object, i get a document with name_fuzzy as an array and all the languages as array elements but all of them are empty.

{
  "name": {
    "en": "Tandoori Maggie",
    "ja": "DMTC"
  },
  "base_price": 123,
  "description": {
    "en": "some test desc",
    "ja": "new testing"
  },
}

same for description field

output:

[{
  "_id": {
    "$oid": "5f46b99ead705f1afcc5e74a"
  },
  "name": {
    "en": "Tandoori Maggie",
    "ja": "DMTC"
  }
  "name_fuzzy": [
    {
      "en_fuzzy": [],
      "ja_fuzzy": [],
      "et_fuzzy": [],
      "ru_fuzzy": [],
      "es_fuzzy": [],
      "de_fuzzy": [],
      "th_fuzzy": [],
      "ms_fuzzy": [],
      "zh_fuzzy": [],
      "fil_fuzzy": []
    }
  ],
  "createdAt": {
    "$date": "2020-08-26T19:35:58.892Z"
  },
  "updatedAt": {
    "$date": "2020-08-26T19:35:58.892Z"
  }
}]

Thanks

Multiple pre-save hook issues

I have a pre-save hook that sets the value of 'this.contents' based on another field. Mongoose Fuzzy Search is set up to search based on 'this.contents'.

I think the pre-save hook that mongoose-fuzzy-searching requires to populate NGrams runs before the pre-save hook I created which populates 'this.contents'; therefore, no NGrams are populated.

Is there a way to specify which order the hooks run in? Can the mongoose-fuzzy-search middleware be post-save?

No results returned with no search term (empty query)

Thanks so much for this package. Works super well from what I can tell!

I'm just having one issue. As demonstrated below, I have a find I replaced with fuzzySearch allowing users to perform a fuzzy search with a ?search=whatever query param. When that's not used, I want my fuzzySearch to return what would be returned by a find with no text search.

const acronyms = await Acronym.fuzzySearch(req.query.search || '')

Am I missing something? If there's a way to make this work, I'd love to know. Otherwise, I'd love some feedback on my PR to make this work: #42

TypeScript support?

Do you want to request a feature, an issue, or report a bug?
Feature-ish

What is the current behaviour?
No TypeScript typings.

If the current behaviour is a bug, please provide the steps to reproduce.

What is the expected behaviour?
To have TypeScript support for type checks and IDE auto-completion.

If this is a feature request, what is the motivation or use case for changing
the behaviour?

TypeScript is widely popular and most packages support it either separately through the @types organization or by including a typings.d.ts file inside the package itself.

Please mention other relevant information such as Node.js and mongoose version.
Node: 12.13.1
Mongoose: 5.9.25

Updating Fields to Empty String

Do you want to request a feature, an issue, or report a bug?
Bug

What is the current behaviour?
Updating a document's fuzzy search field (string) with a new value updates its associated fuzzy array (field _fuzzy). Updating the document's field a second time with an empty string does not update the associated fuzzy array.

If the current behaviour is a bug, please provide the steps to reproduce.

  1. Create a schema with a single string field
  2. Add that field as a mongoose fuzzy searching field
  3. Create a new object with that field as some string that is not empty and insert into database
  4. Update the documents field to be empty
  5. Check the value of the fields associated field _fuzzy array in the database
const mongoose = require("mongoose");
const fuzzy = require("mongoose-fuzzy-searching");

const options = {
  useNewUrlParser: true,
  useUnifiedTopology: true,
  useFindAndModify: false,
  useCreateIndex: true,
};

mongoose.Promise = global.Promise;
mongoose.connect("URL");

const CommentSchema = new mongoose.Schema({ comment: String });
CommentSchema.plugin(fuzzy, { fields: ["comment"] });

const Comment = mongoose.model("Comment", CommentSchema);
module.exports = { Comment };

const comment = new Comment({ comment: "Test" });
try {
  comment.save();

  // Using timeouts in order to view documents in between updates
  setTimeout(() => {
    console.log("updating to empty...");
    comment.comment = "";
    comment.save();
  }, 3000);

  setTimeout(() => {
    console.log('updating to "NEW"...');
    comment.comment = "NEW";
    comment.save();
  }, 6000);
} catch (e) {
  console.log(e);
}

Initial Document

{
    "_id" : ObjectId("5fc7e091081cba2e17c6a849"),
    "comment_fuzzy" : [ 
        "st", 
        "es", 
        "te", 
        "est", 
        "tes", 
        "test"
    ],
    "comment" : "Test",
    "__v" : 0
}

Empty Update

{
    "_id" : ObjectId("5fc7e091081cba2e17c6a849"),
    "comment_fuzzy" : [ 
        "st", 
        "es", 
        "te", 
        "est", 
        "tes", 
        "test"
    ],
    "comment" : "",
    "__v" : 0
}

Final Update

{
    "_id" : ObjectId("5fc7e091081cba2e17c6a849"),
    "comment_fuzzy" : [ 
        "ew", 
        "ne", 
        "new"
    ],
    "comment" : "NEW",
    "__v" : 1
}

What is the expected behaviour?
The field _fuzzy array updates to empty when it's associated field is set to an empty string.

Please mention other relevant information such as Node.js and mongoose version.
Mongoose Fuzzy Searching v2.0.2
Mongoose v5.11.1
Node v12.20.0

How to handle nested field? The Anagram is not created under info.name1

My model looks like this:

const taskSchema = new mongoose.Schema({
  name: {
    type: String,
    required: true
  },
  info: {
    name1: String,
    title: String,
    version: String,
    description: String
  },
  completed: {
    type: Boolean,
    required: true
  },
  user: {
    type: mongoose.Schema.Types.ObjectId,
    ref: 'User'
  }
}, {
    timestamps: true
});

taskSchema.plugin( mongoose_fuzzy_searching, {
    fields: [{
        name: 'info.name1',
        minSize: 2,
        prefixOnly: false,
    }]
    }
);

I saved :

 const debug = require('debug')('add_new_task');
    const input = {
        name: taskTitle,
        info: {
            name1: "Army Ants1",
            title: "Army Ants2",
            version: "Army Ants3",
            description: "Army Ants4"
        },
        completed: false
    };
    try {
        const user = await User.findOne({email: taskEmail});
        debug(`user ${JSON.stringify(user, null,2)}`);
        const task = new Task({...input, user: user.id});
        const result = await task.save();
        user.tasks.push(result.id);
        await user.save();
        debug(`result=${JSON.stringify(result, null,2)}`);
        return result;
    } catch (error) {
        console.log(error);
    }

The Anagram is not created under info.name1:

add_new_task result={
add_new_task "info": {
add_new_task "name1_fuzzy": [
add_new_task ""
add_new_task ],
add_new_task "name1": "Army Ants1",
add_new_task "title": "Army Ants2",
add_new_task "version": "Army Ants3",
add_new_task "description": "Army Ants4"
add_new_task },
add_new_task "_id": "5fb3130d6d087b31b974acff",
add_new_task "name": "Army of Ants",
add_new_task "completed": false,
add_new_task "user": "5f91caa051fa0512993e9326",
add_new_task "createdAt": "2020-11-17T00:02:22.006Z",
add_new_task "updatedAt": "2020-11-17T00:02:22.006Z",
add_new_task "__v": 0
add_new_task } +167ms

name1_fuzzy is empty.

Update mongoose version to 6.x.x

Do you want to request a feature, an issue, or report a bug?
Issue

What is the current behaviour?
Outdated mongoose peer dependency version.

If the current behaviour is a bug, please provide the steps to reproduce.

What is the expected behaviour?
Please update this version

If this is a feature request, what is the motivation or use case for changing
the behaviour?

Support for newest mongoose version.

Please mention other relevant information such as Node.js and mongoose version.

Add option to use $all filter instead of $text search

Do you want to request a feature, an issue, or report a bug?
feature

What is the current behaviour?
Current behavior is to use $text query to search the collection. This gives inaccurate results because of lots of partial matches when searching multiple small common phrases.
Eg. when searching "prime bank" it is currently giving results which have only one of these at the top instead of the document which has both.

If the current behaviour is a bug, please provide the steps to reproduce.

What is the expected behaviour?
An option where only results are returned which contain all phrases searched. I was thinking how to do this, and instead of using $text search if I instead search the fuzzy array with {$all : } it gives better results.

If this is a feature request, what is the motivation or use case for changing
the behaviour?

Limiting results when larger search query.

Please mention other relevant information such as Node.js and mongoose version.
Node: 14
Mongoose: 5.10

Pre-save hook removed, still can't find any user

Works perfectly with other collections, _fuzzy fields are all created

const userSchema = new mongoose.Schema({
    createdAt: { type: Date, default: new Date() },
    email: { type: String, required: true, unique: true },
    emailConfirmed: { type: Boolean, default: false },
    emailToken: { type: String, default: crypto.randomBytes(16).toString('hex')},
    password: {type: String, required: true},
    passwordResetToken: String,
    passwordResetExpires: Date,


    firstName: {type: String, required: true},
    lastName: String,

}, { timestamps: true });

/*
/**
 * Password hash middleware.
 */
/*
userSchema.pre("save", function (next) {
    const user = this as IUser;
    bcrypt.hash(user.password, 10, (err, hash) => {
        user.password = hash;
        next();
    });
});

userSchema.pre("update", function (next) {
    const modifiedPassword = this.getUpdate().$set.password;

    if (!modifiedPassword)
        return next();

    try {
        bcrypt.hash(modifiedPassword, 10, (err, hash) => {
            this.getUpdate().$set.password = hash;
            next();
        });
    } catch (error) {
        return next(error);
    }
});
*/

userSchema.methods.comparePassword = function (candidatePassword: string): Promise<boolean> {
    let password = this.password;
    return new Promise((resolve, reject) => {
        bcrypt.compare(candidatePassword, password, (err, success) => {
            if (err) return reject(err);
            return resolve(success);
        });
    });
};

userSchema.plugin(mongoose_fuzzy_searching, {fields: [
        {
            name: 'firstName',
            weight: 10,
        },
        {
            name: 'lastName',
            weight: 5,
        },
    ]
});

export const User = mongoose.model<IUser>("User", userSchema);

export default User;

Having some doubts about the created index and internal behaviour

Hi, I just installed your plugin and making some unit testing with my use case I have some troubles. Let's say I have the next basic schema:

const articleSchema = new mongoose.Schema({
  title: {
    en: String,
    es: String,
  }
 // ... 
 otherProp: Boolean
}):

I want the fuzzy search to be in the two nested keys of the title, so I use the plugin according to your api:

articleSchema.plugin(fuzzySearch, {
  fields: [
    {
      name: 'title',
      keys: ['en', 'es'],
      minSize: 3
    }
  ]
});

Let's say i create the next document with title:

await new Article ({
  title: {
    en: 'This is an article title in english',
    es: 'A title that is supposed to be in spanish'
  }
},
// ...
).save();

After I check the database the n-grams are generated correctly and exist in the database.

 title_fuzzy: [
    {
      en_fuzzy: [
        'his',
        'thi',
        'this',
        'is',
        'an',
        'cle',
        'icl',
        'tic',
        'rti',
// ...
     ]

All cool, BUT when I did my testing, for example with the string 'cle' which is part of the n-grams array I have no results, not even when using more words, included in the n-gram array like: 'arti' or 'artic'. The only way I get results is by writing the whole word 'article' which afaik is the default behaviour of the native mongodb text search.

While doing more debugging I printed the generated indexes and with surprise I saw that the text index is in the original field, this is the index object I get back:

{
    v: 2,
    key: { _fts: 'text', _ftsx: 1 },
    name: 'title.es_text_title.en_text',
    ns: 'LocalTest.articles',
    background: true,
    weights: { 'title.en': 1, 'title.es': 1 },
    default_language: 'english',
    language_override: 'language',
    textIndexVersion: 3
  }

Am I doing something wrong? Or why the index is not pointed to the generated n-gram arrays? If not, what's happening?

Also, is there any way to override the default language? In the docs, mongo can work with different languages.

Thank you in advance.

Retroactive Adding Ngrams to Documents

I am adding the plugin to an existing mongo database. Is there a recommended way to update all pre-existing documents with ngrams (ie "userName_fuzzy")?

This would be great to addition to the readme.

Thank you!

Search in Referenced Object Id Field

Do you want to request a feature, an issue, or report a bug?
feature

What is the current behaviour?
Does not look into referenced object title or name.

If the current behaviour is a bug, please provide the steps to reproduce.

What is the expected behaviour?
Need to search in referenced object e,g; A product has field category (object Id) and if a user search for for example 'laptop' it should search for laptop in product name, keywords and title of category too, but the category filed id object id refernce.

If this is a feature request, what is the motivation or use case for changing
the behaviour?

Please mention other relevant information such as Node.js and mongoose version.

Cannot find some string values

--When I search for 'ano' I get this:
Mongoose: tasks.find({ '$text': { '$search': 'no an ano' } }, { projection: {} })
Mongoose: tasks.find({ '$text': { '$search': 'no an ano' } }, { projection: {} })
search Yet Another Completely unrelated name +0ms
search Another Completely unrelated name +0ms

--With 'another, I get these hits:

Mongoose: tasks.find({ '$text': { '$search': 'er he th ot no an her the oth not ano ther othe noth anot other nothe anoth nother anothe another' } }, { projection: {} })
Mongoose: tasks.find({ '$text': { '$search': 'er he th ot no an her the oth not ano ther othe noth anot other nothe anoth nother anothe another' } }, { projection: {} })
search Yet Another Completely unrelated name +0ms
search Another Completely unrelated name +0ms

--Searching for 'ye', I get hits:
Mongoose: tasks.find({ '$text': { '$search': 'ye' } }, { projection: {} })
Mongoose: tasks.find({ '$text': { '$search': 'ye' } }, { projection: {} })
search Yet Another Completely unrelated name +0ms

--Searching for 'an', I don't get any hits:

--But when I search 'an' I do not get any hit:
Mongoose: tasks.find({ '$text': { '$search': 'an' } }, { projection: {} })
Mongoose: tasks.find({ '$text': { '$search': 'an' } }, { projection: {} })

How come 'an' is not found and yet 'ye' was found?

Not using fuzzySearch() seemed to work, I can get hits for 'an'

const queryOverride = {
'$or':
[
{'info_fuzzy.name1_fuzzy': {'$regex': ^${searchValue}}},
{'info_fuzzy.title_fuzzy': {'$regex': ^${searchValue}}},
{'info_fuzzy.version_fuzzy': {'$regex': ^${searchValue}}},
{'info_fuzzy.description_fuzzy': {'$regex': ^${searchValue}}}
]
}
const results = await Task
.find(queryOverride)
// .fuzzySearch(searchValue)
.exec();

Mongoose: tasks.find({ '$or': [ { 'info_fuzzy.name1_fuzzy': { '$regex': '^an' } }, { 'info_fuzzy.title_fuzzy': { '$regex': '^an' } }, { 'info_fuzzy.version_fuzzy': { '$regex': '^an' } }, { 'info_fuzzy.description_fuzzy': { '$regex': '^an' } } ] }, { projection: {} })
Mongoose: tasks.createIndex({ 'info_fuzzy.name1_fuzzy': 'text', 'info_fuzzy.title_fuzzy': 'text', 'info_fuzzy.version_fuzzy': 'text', 'info_fuzzy.description_fuzzy': 'text' }, { weights: {}, name: 'fuzzy_text', background: true })
search Army of Ants +0ms
search Army Ants +0ms
search Ant Man +0ms
search Another Completely unrelated name +0ms
search Yet Another Completely unrelated name +1ms


Heres my schema:

const mongoose = require('mongoose');
const mongoose_fuzzy_searching = require('mongoose-fuzzy-searching');

const taskSchema = new mongoose.Schema({
name: {
type: String,
required: true
},
environment: {
type: String,
required: true
},
info: {
name1: String,
title: String,
version: String,
description: String
},
completed: {
type: Boolean,
required: true
},
user: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
}
}, {
timestamps: true
});

// NOTE: Index need to be dropped and re-created each time fields are updated
taskSchema.plugin( mongoose_fuzzy_searching, {
fields: [
// {
// name: 'name',
// minSize: 1,
// prefixOnly: false,
// },
{
name: 'info',
minSize: 2,
prefixOnly: false,
keys: [
'name1',
'title',
'version',
'description'
]
}
]
}
);

module.exports = mongoose.model('Task', taskSchema);

TypeError: obj.fromObjectKeys is not a function

const mongoose = require('mongoose');
const mongooseFuzzySearching = require('mongoose-fuzzy-searching');
const updateFuzzy = require('../lib/updateModel');

/* const mongoosastic = require('mongoosastic');
const esClient = require('../searchConnection'); */

const RecipeSchema = mongoose.Schema({
title: {
type: String,
required: true,
},
category: {
type: mongoose.ObjectId,
ref: 'RecipeCategory',
},
tags: [{
family: {
type: String,
required: true,
},
title: {
type: String,
},
}],
previewImg: {
type: String,
required: true,
},
likes: {
type: Number,
default: 0,
},
time: {
type: Number,
default: 0,
},
portions: {
type: Number,
default: 1,
},
comments: [{
type: mongoose.ObjectId,
ref: 'Comment',
}],
products: [{
product: {
type: mongoose.ObjectId,
ref: 'Product',
},
value: {
type: Number,
default: 0,
},
valueType: { // 'volume', 'weight', 'count'
type: String,
default: 'count',
},
measureObj: {
measuringInstrument: {
type: mongoose.ObjectId,
ref: 'MeasuringInstrument',
},
count: {
type: Number,
default: 0,
},
},
}],
steps: [{
source: {
type: String,
},
type: {
type: String,
},
start: {
type: String,
},
end: {
type: String,
},
text: {
type: String,
required: true,
},
}],
active: {
type: Boolean,
default: true,
},
});

RecipeSchema.plugin(mongooseFuzzySearching, {
fields: [{
name: 'title',
minSize: 5,
},
{
name: 'tags',
keys: ['title'],
},
],
});

Getting the error "TypeError: obj.fromObjectKeys is not a function" when adding some objects or trying to work with pre-existing data or tryng to search something
Though, fuzzy objects are created o_O

Not working with other plugins

Hi, thank you for the great plugin.
Found a issue tough.
Iam trying to use it with another plugin(mongoose-paginate) and had no luck yet...
Here's my router's code

// -Get all users sorted by name
router.get('/', async (req, res) => {
	let users_to_return;
	const search_param = req.query.search;

	if(search_param)
		users_to_return = await User.fuzzySearch(search_param).select('-password');
	else
		users_to_return = await User.paginate({}, {...res.locals.pagination, sort: 'name', select: '-password' });

	log.silly(`Users', ${JSON.stringify(users_to_return)})`);
	log.silly(`Users', ${JSON.stringify(Envelope.paginated(users_to_return))}`);

	res.json(Envelope.paginated(users_to_return));
});

I am trying to do something like
users_to_return = await User.fuzzySearch(search_param).paginate({}, {...res.locals.pagination, select: '-password' });

Any ideas?

Specify an array field of strings

My document has an array field of strings that will be used as keywords or tags, currently this will trhow the error text.split is not a function, my quick fix was to check if text is an array and join the elements:

 if (Array.isArray(text)) {
    if (text.length === 0) {
        return [];
    }
    text = text.join(' ');
}

How to use with Aggregation?

Do you want to request a feature, an issue, or report a bug?
A feature

What is the current behaviour?
Doesn't work with aggregate

If the current behaviour is a bug, please provide the steps to reproduce.

What is the expected behaviour?

  • should work with aggregation pipeline with pagination (skip & limit)

If this is a feature request, what is the motivation or use case for changing
the behaviour?

  • Let say I am using an aggregation pipeline for a query and want to filter data based on search

Please mention other relevant information such as Node.js and mongoose version.

How can I implement the partial index on this package ?

Do you want to request a feature, an issue, or report a bug?

What is the current behaviour?

If the current behaviour is a bug, please provide the steps to reproduce.

What is the expected behaviour?

If this is a feature request, what is the motivation or use case for changing
the behaviour?

Please mention other relevant information such as Node.js and mongoose version.

Search not working with object data

Do you want to request a feature, an issue, or report a bug?
Yes

What is the current behaviour?
Can't search with index and object data

If the current behaviour is a bug, please provide the steps to reproduce.
I create user Schema with fuzzy search plugin as below

const UserSchema = new Schema({
  name: {
    firstName: String,
    lastName: String
  },
  email: String
},{timestamps: true});
UserSchema.index({"$**": "text"});
UserSchema.plugin(mongoose_fuzzy_searching, { fields: ['name.firstName', 'name.lastName', 'email'] });
const User = mongoose.model('User', UserSchema);

When try to search with firstname or last name it's return no results while already have results
User.fuzzySearch({query: 'jo'}).sort({ age: -1 }).exec();
Also check in mongoose database email_fuzzy have data but firstName_fuzzy haven't data

What is the expected behaviour?
Return results when add data as new User({ email : "[email protected]",name : {firstName: 'John A', lastName: 'Deo'}});
If this is a feature request, what is the motivation or use case for changing
the behaviour?

No
Please mention other relevant information such as Node.js and mongoose version.
Node : 16.6.2
Mongoose : 5.10.19

Return 'matched word' metadata with search results

It would be great if, after a fuzzy search is performed, some metadata is returned about what word was used to match.

(The confidenceScore is returned, which is helpful, but it would be great if the search response also included the nGram / word with highest similarity to the input text).

Format data before making ngrams

Do you want to request a feature, an issue, or report a bug?
feature
What is the current behaviour?
Ngrams are created directly from data

What is the expected behaviour?
Having an option to format or parse data first

If this is a feature request, what is the motivation or use case for changing
the behaviour?

For example, I want to search by date by writing the date in a certain format i.e: 'DD/MM/YYYY', therefore having an option to format the field as I like would be a really useful feature

I.E

{
  name: 'date',
  format: date => dayjs(date).format('DD/MM/YYYY') 
}

I can work on this feature if we agree that is relevant and on how it's going to be implemented

how to show some related data if no data found?

Do you want to request a feature, an issue, or report a bug?
Yes
What is the current behaviour?
If the query doesn't match, it gives no output.
If the current behaviour is a bug, please provide the steps to reproduce.

What is the expected behaviour?
Can we have a filter like if no result fount then send some other results where query at least matches with the few letters of the data
If this is a feature request, what is the motivation or use case for changing
the behaviour?

it sends empty array if not result found
Please mention other relevant information such as Node.js and mongoose version.
Node 16.8.0
mongoose 6.0.5

Access confidence score

The confidence score for some reason isnt accessible from the array of objects it returns.
my code:

  await Card.fuzzySearch({ query: req.params.name, limit: 10 })
    .then(card => {
      for (let i = 0; i < card.length; i++) {
        console.log(card[i].confidenceScore);
      }
      cards = card;
    });

Exact match result is not the first item returned

Do you want to request a feature, an issue, or report a bug?
Issue

What is the current behaviour?
Exact match result is not the first item returned

If the current behaviour is a bug, please provide the steps to reproduce.
This is the returned array for the query=lille with City.fuzzySearch(query).limit(5).exec() :

[
  { "nom": "Lillers",      "confidenceScore": 4.300000000000001 },
  { "nom": "Lillemer",     "confidenceScore": 4.300000000000001 },
  { "nom": "Lille",        "confidenceScore": 4.300000000000001 },
  { "nom": "Lillebonne",   "confidenceScore": 4.300000000000001 },
  { "nom": "Ille-sur-Têt", "confidenceScore": 4.2               }
]

What is the expected behaviour?
Exact match "Lille" should have a higher confidenceScore than the others

I'm using this function to bring the exact match up :

for (let i=0; i<answer.length; i++) {
    if (answer[i].nom.toLowerCase() === query) {
        answer.unshift(answer[i]);
        answer.splice(i+1,1);
    }
}

If this is a feature request, what is the motivation or use case for changing
the behaviour?

Please mention other relevant information such as Node.js and mongoose version.
node v14.4.0
mongoose 5.11.15

Getting MongoServerError: language override unsupported when plugin is used in a collection with the field language with invalid values

Do you want to request a feature, an issue, or report a bug?
bug

What is the current behaviour?
I know this repository seems like is no longer maintained, I had to fork this to fix the issue but just in case it gets picked up again.

The plugin always sets the "language override" to its default value of language. This is an issue when the collection
documents already have the language field with values not compatible with MongoDB or are expected to be used in another way different from what the index intends to use it for. This can either make the creation of the index to fail or throw an error when trying to save a document with a non-valid value.

In my case, I have a collection where I store the preferred language of a user in the field language, the plugin is not compatible since I have documents whose language value is en-US

If the current behaviour is a bug, please provide the steps to reproduce.

const mongoose = require('mongoose')
const fuzzySearchPlugin = require('mongoose-fuzzy-searching')

const schema = new Schema({
  name: { type: String },
  language: { type: String },
}, { collection: 'User' })


schema.plugin(fuzzySearchPlugin, {
  fields: [{
    name: 'name',
    minSize: 3,
    weight: 3,
    prefixOnly: true,
  }],
})

const User = model('User', schema)

const myUser = new User({ name: 'John', language: 'en-US' })
myUser.save() // this promise will be rejected with `MongoServerError: language override unsupported: en-US`

What is the expected behaviour?
Allow the plugin to accept the override_language option for cases like this where changing the name of a field in a collection is not feasible, something like

schema.plugin(fuzzySearchPlugin, {
  fields: [{
    name: 'name',
    minSize: 3,
    weight: 3,
    prefixOnly: true,
  }],
language_override: 'document_language',
})

If this is a feature request, what is the motivation or use case for changing
the behaviour?

Please mention other relevant information such as Node.js and mongoose version.

Working with unique values

Do you want to request a feature, an issue, or report a bug?
A feature I guess.
What is the current behaviour?

If the current behaviour is a bug, please provide the steps to reproduce.

What is the expected behaviour?
A way to filters the result by unique value. For examples, I got multiple documents with a "name" value. If I got multiple documents with same name, filtering them to get only one.
I know I can use distinct, but distinct is filtering, but returning only the fields you requested.

If this is a feature request, what is the motivation or use case for changing
the behaviour?

I actually need for filtering my +35 000 movies db where there is some duplicates, and I need to keep them in db, but I need for search to avoid duplicates. Thank you !
Please mention other relevant information such as Node.js and mongoose version.

Results accuracy

Do you want to request a feature, an issue, or report a bug?
issue

What is the current behaviour?
I cant find a way to improve results accuracy.
I'm using this package to get users that have email similar to a particular one.
I would like to find something like "[email protected]" and "[email protected] as match of "[email protected]", but right now i got matches really different from my search email.
I can even find null values in results.
I tried to change minsize and weight values unsuccessfully

If the current behaviour is a bug, please provide the steps to reproduce.

What is the expected behaviour?

If this is a feature request, what is the motivation or use case for changing
the behaviour?

Please mention other relevant information such as Node.js and mongoose version.
Using mongo 3.6, node 10.23 and version 2.0.2 of this package.

No output except Query object

Hello,
So I have an issue that I can’t seem to track down.
Using your simple implementation: If I use promises, I get nothing. If I assign Model.fuzzySearch(…) to a variable and console.log the variable, I get a Query object that contains schema…collection name...search anagram etc.
Below is the bit of code that spits out the Query object. A gist of the output is here

const mongoose_fuzzy_searching = require('mongoose-fuzzy-searching');
const mongoose = require('mongoose')
const { Schema } = mongoose

const UserSchema = new Schema({
  firstName: String,
  lastName: String,
  email: String,
  age: Number,
});

UserSchema.plugin(mongoose_fuzzy_searching, { fields: ['firstName', 'lastName'] });

const User = mongoose.model('User', UserSchema);

const user = new User({ firstName: 'Joseph', lastName: 'Doe', email: '[email protected]', age: 30 });

try {
  user.save();
  const users = User.fuzzySearch('joe');
  console.log(users);

} catch (e) {
  console.error(e);
}

I tried an implementation on my atlas db-collection and got the same result.
I’m not sure if I’m overlooking a dependency (I never got any errors), or if there’s an issue with the versions of node, mongoose. I'm not sure how to go about debugging this issue.
Software versions of pertinence:
mongoose: 5.9.20
mongodb: 3.5.9
node: 14.4.0
mongoose-fuzzy-searching: 1.3.1

pre-existing data

Hi, thanks for the great plugin.
I've used pre-existing data update differently tough.
It uses Promise.all to update docs in database instead of async and queue from async as

follows:

const updateFuzzy = async (Model, attrs) => {
   const docs = await Model.find();

   const updateToDatabase = async data => {
      try {
         if(attrs && attrs.length) {
            const obj = attrs.reduce((acc, attr) => ({ ...acc, [attr]: data[attr] }), {});
            return Model.findByIdAndUpdate(data._id, obj).exec();
         }

         return Model.findByIdAndUpdate(data._id, data).exec();
      } catch (e) {
         console.error(e);
      }
   };

   await Promise.all(docs.map(doc => updateToDatabase(doc)));
}

// usage
updateFuzzy(User, ['firstName']);

can you consider it to update docs?
i've also tried to contribute with your project but count find a CONTRIBUTING.md and i dont have permissions to create branchs and create pull requests...
Can you also consider adding it?
thx, very much, hope hearing from you soon.

Fuzzy search same model, but different fields

Hi.

I have and model named Article that contains the tilte and content .

let mongoose = require('mongoose');
let Schema = mongoose.Schema;  
var mongoose_fuzzy_searching = require('mongoose-fuzzy-searching');

var ArticleSchema = new Schema({
    title: {
        type: String,
    },
   content: {
        type: String,
    },
})

module.exports = mongoose.model('Article', ArticleSchema);

The model is exported and used in another .js.
How can I fuzzy search the title and content separately, without declaring

ArticleSchema.plugin(mongoose_fuzzy_searching, {fields: ['title', 'content']});

in the model schema file?

I want to have 2 functions that search articles one by the title, and the other one by the content, separately.

If I put the

ArticleSchema.plugin(mongoose_fuzzy_searching, {fields: ['title', 'content']});

then my both functions will use title and content for the fuzzy search.

Can I achieve something like this?

function a() {
    ArticleSchema.plugin(mongoose_fuzzy_searching, {fields: ['title']});
    fuzzySearch();
}
function b() {
    ArticleSchema.plugin(mongoose_fuzzy_searching, {fields: ['content']});
    fuzzySearch();
}

toJSON and toObject transform do not work any more

This two lines overrides transform method declared on schema level:

https://github.com/VassilisPallas/mongoose-fuzzy-searching/blob/master/index.js#L331

So, after adding this plugin it's impossible to use your own transformations.

const projectSchema = mongoose.Schema({
  _id: {
    type: ShortId, len: 5, base: 62, retries: 4,
  },
  name: {
    type: String,
    maxlength: 255,
  },
}, {
  timestamps: true,
  versionKey: false,
  toJSON: {
    virtuals: true,
    transform(doc, ret) {
      console.log('>>>> toJSON transform will never calls')
      return ret
    },
  },
  toObject: {
    virtuals: true,
    transform(doc, ret) {
      console.log('>>>>> toObject transform will never calls')
      return ret
    },
  },
})

"Key" param in options object only works with object arrays

The document that I am to query has a structure similar to this one:

var BookSchema = new Schema({
    iban: String,
    author: String,
    publisher: String
    name: {
          en: String,
          fi: String,
          sv: String
     }
});

Now, I would like to perform a fuzzy search using as fields name.en, name.fi, name.sv

The documentation states the following about using key into fields array of objects:

If the type of the collection attribute is Object, you can define which attributes will be used for fuzzy searching

Thus I, specified the fields object on which to build the n-grams like this:

BookSchema.plugin(mongoose_fuzzy_searching, {
    fields: [{
            name: 'name',
            keys: ["en", "fi", "sv"]
        }]   
});

This leads to errors during document insertion because the objectKeysCb expects to find an array of objects rather than a single one and the forEach method is not defined.

Also, the example provided uses an array of objects instead of an object as stated in the cited documentation. I think this case should be also handled by the function.

If you agree I will open a pull request and push a fix to this issue.

Any way to use projections on the fuzzySearch function?

Do you want to request a feature, an issue, or report a bug?
New feature

What is the current behaviour?
Model.fuzzySearch() doesn't provide projections.

If the current behaviour is a bug, please provide the steps to reproduce.

What is the expected behaviour?
To accept projections through Model.fuzzySearch() parameters.

If this is a feature request, what is the motivation or use case for changing
the behaviour?

Makes the API more in-line with Mongoose API and results in less repetitive and cleaner code.

Please mention other relevant information such as Node.js and mongoose version.
Node: 12.13.1
Mongoose: 5.9.25

unaccurate search

Hello, I'm was looking for a fuzzy search before learning elasticsearch/lucene and then I found your plugin. But I'm having some really unaccurate results
Here is what I got for fuzzy fields:
fields: [{
name: 'name',
minSize: 3,
weight: 10,
}
}]
(I did it like that just to try you plugin)

But with the plainText "mart" I'm getting items with field "name" that doesn't contain "mart" or similar (e.g : "Ceinture Noire de Frank Lee Bruce"), but it contains "mart" in other fields (e.g: description: "Célèbre combattant du dimanche, Frank s'est reconverti dans les arts martiaux après avoir lamentablement raté son diplôme de tailleur de pierres.")

So I tried to add the field description like that :
{
name: 'description',
minSize: 10,
weight: 0
}
But "mart" is still returning the same data.

In my data i'm having a LOT of items with "marteau ...."

Am I doing something bad ? Did I missed something ?

Thanks a lot

Provide query helper instead of static method

Do you want to request a feature, an issue, or report a bug?

Feature

What is the current behaviour?

If the current behaviour is a bug, please provide the steps to reproduce.

Currently fuzzySearch is only available through the Model static function. But if I have a function that returns me a Query instance then I am not able to add fuzzy search constraints to that query.

What is the expected behaviour?

Use the official recommended way of registering a query helper instead of adding statics, https://mongoosejs.com/docs/guide.html#query-helpers

If this is a feature request, what is the motivation or use case for changing
the behaviour?

This would allow using fuzzySearch functionality while dynamically creating queries.

Please mention other relevant information such as Node.js and mongoose version.
Node: 10.16
Mongoose: 5.9.14

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.