Mongodb部分匹配

时间:2016-11-26 11:55:18

标签: javascript regex mongodb levenshtein-distance fuzzy-search

如何使用一个levenshtein距离获取mongodb中的所有文档。

我收集了足球队。

{
    name: 'Real Madrir',
    nicknames: ['Real', 'Madrid', 'Real Madrir' ... ]
}

用户搜索Real Madid的{​​{1}}或其他内容。

我想将包含0或1个levenshtein距离的昵称的所有文档返回到给定的搜索字符串。

我认为有两种方法,mongodb全文搜索或正则表达式。

那么我可以编写这样的正则表达式或查询吗?

谢谢。

1 个答案:

答案 0 :(得分:4)

对于全文搜索,首先您必须在nicknames字段上创建Text Index。在创建索引之前插入的文档将无法搜索。该搜索仅适用于创建索引后已插入的文档。然后,当您使用MongoDb的$text$search运算符执行搜索时,MongoDb将返回nicknames字段对应于搜索文本的文档。对于正则表达式匹配,MongoDb有一个$regex运算符,您可以使用。

以下是一些简短的例子:

全文搜索

  1. 将此脚本另存为football.js。它将创建一个带有文本索引的teams集合和两个供我们搜索的文档。
  2. // create football database
    var db = connect("localhost:27017/football");
    
    /* 
       note:
       You may also create indexes from your console
       using the MongoDb shell. Actually each of these
       statements may be run from the shell. I'm using
       a script file for convenience.
    */
    
    // create Text Index on the 'nicknames' field 
    // so full-text search works
    db.teams.createIndex({"nicknames":"text"});
    
    // insert two teams to search for
    db.teams.insert({
        name: 'Real Madrir',
        nicknames: ['Real', 'Madrid', 'Real Madrir' ]
    })
    
    db.teams.insert({
        name: 'Fake Madrir',
        nicknames: ['Fake']
    })
    
    1. 打开终端并导航到保存football.js的目录,然后键入mongo football.js,针对本地MongoDb实例运行此脚本。

    2. 从终端输入mongo以打开MongoDb Shell并通过键入football切换到use football数据库。

    3. 进入足球数据库后,使用db.teams.find({"$text":{"$search":"<search-text>"}})

    4. 搜索您的某个文档
      > use football
      
      // find Real Madrir
      > db.teams.find({"$text":{"$search":"Real"}})
      
      // find Fake Madrir
      > db.teams.find({"$text":{"$search":"Fake"}})
      

      <强>正则表达式

      如果要使用正则表达式进行搜索,则无需创建索引。只需使用mongodb的$regex运算符进行搜索:

      //find Real Madrir
      db.teams.find({"nicknames": {"$regex": /Real/}})
      
      db.teams.find({"nicknames": {"$regex": /Real Madrir/}})
      
      //find Fake Madrir
      db.teams.find({"nicknames": {"$regex": /Fa/}})
      
      db.teams.find({"nicknames": {"$regex": /ke/}})
      

      <强>猫鼬

      这就是每个搜索在NodeJS中使用mongoose

      的方式
      var searchText = "Madrir"; // or some value from request.body
      
      var searchRegex = new RegExp(searchText);
      
      var fullTextSearchOptions = {
        "$text":{
          "$search": searchText
        }
      };
      
      var regexSearchOptions = {
        "nicknames": {
          "$regex": searchRegex
        }
      };
      
      // full-text search
      Team.find(fullTextSearchOptions, function(err, teams){
      
        if(err){
          // ...
        }else if(teams){
          // ...
        }
      
      })
      
      // regex search
      Team.find(regexSearchOptions, function(err, teams){
      
        if(err){
          // ...
        }else if(teams){
          // ...
        }
      
      })