vassilispallas / mongoose-fuzzy-searching Goto Github PK
View Code? Open in Web Editor NEWMongoose Fuzzy Searching Plugin
Home Page: https://www.npmjs.com/package/mongoose-fuzzy-searching
License: MIT License
Mongoose Fuzzy Searching Plugin
Home Page: https://www.npmjs.com/package/mongoose-fuzzy-searching
License: MIT License
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
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.
--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);
(node:11396) DeprecationWarning: Mongoose: findOneAndUpdate()
and findOneAndDelete()
without the useFindAndModify
option set to false are deprecated. See: https://mongoosejs.com/docs/deprecations.html#findandmodify
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",
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
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;
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;
});
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
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
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
},
},
})
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!
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.
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
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).
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
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
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
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();
}
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.
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
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 ?
Ability to skip and limiting and counting the results would be great as mongoose provides them it self in find() function.
Is there a way to limit the number of search results returned...
Just answered my own question , simply add .limit() to the .fuzzySearch(querykey).limit(10)
https://docs.mongodb.com/manual/reference/method/cursor.limit/
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(' ');
}
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
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
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
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.
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.
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?
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.
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.
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.
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.
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
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?
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?
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?
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.
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.
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
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.
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.
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
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.