使用Mongodb进行模糊搜索?

时间:2016-07-17 13:19:12

标签: mongodb search mongoose

我已设法在我的mongodb应用中设置搜索功能。请参阅下面的代码。这非常有效,但它只返回确切的结果。如何更改代码以使其接受更“模糊”的搜索结果?谢谢!

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});
       }
    });
});

4 个答案:

答案 0 :(得分:22)

我相信要进行“模糊”搜索,你需要使用正则表达式。这应该完成你正在寻找的东西(escapeRegex函数源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 });
           }
       }); 
    }
}

话虽这么说,您的应用程序在使用正则表达式查询mongo时可能会遇到性能问题。使用像search-index这样的库进行搜索可以帮助优化应用程序的性能,还可以搜索词干(例如从“查找”返回“找到”)。

更新:我的原始答案包括一个简单的常规表达,会使您的应用容易受regex DDoS attack攻击。我已经更新了“安全”转义的正则表达式。

答案 1 :(得分:1)

我知道这是一个旧线程,但是我制作了一个基于this article的插件。

mongoose-fuzzy-searching

(为了更快的结果,它使用declare -- CLEANED_KEY="RPD-API.pem" 而不是$text的查询运算符)

下面的示例仅根据标题和城市搜索事件

$regex

答案 2 :(得分:1)

您可以使用 Mongo DB Atlas 功能,您可以根据 MongoDB 提供的不同 Analyzers 搜索您的文本。 然后你可以像这样进行搜索: 如果没有模糊对象,它将进行全文匹配搜索。

$search:{
 {
  index: 'analyzer_name_created_from_atlas_search',
  text: {
    query: 'Russ has denied involvement in the case',
    path: 'sentence',
    fuzzy:{
      maxEdits: 2
    }
  }
 }
}

答案 3 :(得分:0)

如果您正在使用 atlas,请转到索引选项卡为您的数据库创建索引,然后您可以使用聚合进行更强大的模糊搜索。

Jobs.aggregate([
    {
        $search: {
            "index": "default",
            "text": {
                "path": "name",
                "query": req.query.search,
            }
        }
    },
], (err: any, data: any) => {
    if (err) {
        res.status(500).send(err);
    }
    else {
        res.status(200).send(data);
    }
}).limit(20)