I have managed to set up a search feature in my mongodb app. See the code below. This works very well however it only returns exact results. How would I change my code to make it accept more "fuzzy" search results? Thanks!
router.get("/", function(req, res){
if (req.query.search) {
Jobs.find({"name": req.query.search}, function(err, foundjobs){
if(err){
console.log(err);
} else {
res.render("jobs/index",{jobs:foundjobs});
}
});
}
Jobs.find({}, function(err, allJobs){
if(err){
console.log(err);
} else {
res.render("jobs/index",{jobs:allJobs});
}
});
});
I believe that to do "fuzzy" search you will need to use regex. This should accomplish what you're looking for (escapeRegex function source here):
function escapeRegex(text) {
return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
};
router.get("/", function(req, res) {
if (req.query.search) {
const regex = new RegExp(escapeRegex(req.query.search), 'gi');
Jobs.find({ "name": regex }, function(err, foundjobs) {
if(err) {
console.log(err);
} else {
res.render("jobs/index", { jobs: foundjobs });
}
});
}
}
That being said, your application can experience performance issues when querying mongo by regex. Using a library like search-index for search could help optimize your application's performance, with the added benefit of searching word stems (like returning "found" from "find").
UPDATE: My original answer included a simple regular exression that would leave your application vulnerable to a regex DDoS attack. I've updated with a "safe" escaped regex.
I know this is an old thread, but I made a plugin which is based on this article.
(It uses $text query operator instead of $regex, for faster results)
The below example just searches for events based on title and city
const mongoose_fuzzy_searching = require('mongoose-fuzzy-searching');
const schema = {
title: {
type: String,
trim: true,
required: true,
},
description: {
type: String,
trim: true,
},
city: {
type: String,
},
address: {
type: String,
}
};
const EventsSchema = mongoose.Schema(schema);
EventsSchema.plugin(mongoose_fuzzy_searching, {fields: ['title', 'city']});
const Events = mongoose.model('Events', EventsSchema);
Events.fuzzySearch('Nodejs meetup').then(console.log).catch(console.error);
You can use the Mongo DB Atlas feature where you can search your text based on different Analyzers that MongoDB provides. And you can then do a search like this: Without the fuzzy object, it would do a full-text-match search.
$search:{
{
index: 'analyzer_name_created_from_atlas_search',
text: {
query: 'Russ has denied involvement in the case',
path: 'sentence',
fuzzy:{
maxEdits: 2
}
}
}
}