Mongodb数据库的模糊搜索

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mongodb数据库的模糊搜索相关的知识,希望对你有一定的参考价值。

参考技术A 模糊查询简介

MongoDB查询条件可以使用正则表达式,从而实现模糊查询的功能。模糊查询可以使用$regex操作符或直接使用正则表达式对象。

$regex操作符的介绍

MongoDB使用$regex操作符来设置匹配字符串的正则表达式,使用PCRE(Pert Compatible Regular Expression)作为正则表达式语言。

regex操作符

<field>:$regex:/pattern/,$options:’<options>’

<field>:$regex:’pattern’,$options:’<options>’

<field>:$regex:/pattern/<options>

正则表达式对象

<field>: /pattern/<options>$regex与正则表达式对象的区别:

在$in操作符中只能使用正则表达式对象,例如:name:$in:[/^joe/i,/^jack/

在使用隐式的$and操作符中,只能使用$regex,例如:name:$regex:/^jo/i, $nin:['john']

当option选项中包含X或S选项时,只能使用$regex,例如:name:$regex:/m.*line/,$options:"si"

$regex操作符的使用

$regex操作符中的option选项可以改变正则匹配的默认行为,它包括i, m, x以及S四个选项,其含义如下

i 忽略大小写,<field>$regex/pattern/i,设置i选项后,模式中的字母会进行大小写不敏感匹配。

m 多行匹配模式,<field>$regex/pattern/,$options:'m',m选项会更改^和$元字符的默认行为,分别使用与行的开头和结尾匹配,而不是与输入字符串的开头和结尾匹配。

x 忽略非转义的空白字符,<field>:$regex:/pattern/,$options:'m',设置x选项后,正则表达式中的非转义的空白字符将被忽略,同时井号(#)被解释为注释的开头注,只能显式位于option选项中。

s 单行匹配模式<field>:$regex:/pattern/,$options:'s',设置s选项后,会改变模式中的点号(.)元字符的默认行为,它会匹配所有字符,包括换行符(\n),只能显式位于option选项中。

使用$regex操作符时,需要注意下面几个问题:

i,m,x,s可以组合使用,例如:name:$regex:/j*k/,$options:"si"

在设置索弓的字段上进行正则匹配可以提高查询速度,而且当正则表达式使用的是前缀表达式时,查询速度会进一步提高,例如:name:$regex: /^joe/

上面介绍的元字符可能就会让我们在查询的时候出现一些问题,比如有时候想要查询出所有带价格的模糊商品的时候用了.元字符进行模糊搜索,这时候会查询出来全部的数据;

这个时候就需要对模糊查询的条件进行一些操作,转义一下:

nodejs + mongodb实现模糊查询与全文搜索

 

mongodb中的查询条件

 

 

 

关键字说明
$or 或关系
$nor 或关系取反
$gt 大于
$gte 大于等于
$lt 小于
$lte 小于等于
$ne 不等于
$in 在多个值范围内
$nin 不在多个值范围内
$all 匹配数组中多个值
$regex 正则,用于模糊查询
$size 匹配数组大小
$maxDistance 范围查询,距离(基于LBS)
$mod 取模运算
$near 邻域查询,查询附近的位置(基于LBS)
$exists 字段是否存在
$elemMatch 匹配内数组内的元素
$within 范围查询(基于LBS)
$box 范围查询,矩形范围
$center 范围查询,圆形范围
$centerSphere 范围查询,球形范围
$slice 查询字段集合中的元素(比如从第几个之后,第N到第M个元素)

 

mongodb中的查询语句

db.movies.find({‘name‘:/未来/})
db.collection.find( { field: { $regex: ‘acme.*corp‘, $options: ‘i‘ } } );

官方举例是通过 ‘/.../‘ 和$regex,这两种都可以查询到结果。

现在我想实现查询标题关键字匹配到对应文章。

如下:

1.查询title字段中包含某个字符串的集合:

 Article.find({"title":{$regex: /searchValue/,$options:‘i‘}}, (err, data) => { // {"title": /searchValue/} $options:‘i‘ 表示忽略大小写
        if(err) {
            console.log(err)
            return res.status(500).json({
                result: 1,
                error_info: err.message
            })
        }
        console.log(data)
        let length = data.length
        return res.status(200).json({
            result: 0,
            count: length,
            searchArticle: data
        })
    })
searchValue是前端传过来的查询关键词。

这么写好像没有问题,跟官方实例一样,但是查询不到结果。

请注意,MongoDB的的模糊查询是通过正则表达式实现的,对应mongodb中,可以直接使用 ‘/../’ 斜杠。
但是在nodejs中,必须要使用RegExp,来构建正则表达式对象。

router.post(‘/like_article_search‘, (req,res) => {
    let searchValue = req.body.value
    console.log(searchValue)
    var str=".*"+searchValue+".*$"
    var reg = new RegExp(str)

    Article.find({"title":{$regex:reg,$options: ‘i‘}}, (err, data) => { // $options:‘i‘ 表示忽略大小写
        if(err) {
            console.log(err)
            return res.status(500).json({
                result: 1,
                error_info: err.message
            })
        }
        console.log(data)
        let length = data.length
        return res.status(200).json({
            result: 0,
            count: length,
            searchArticle: data
        })
    })
})

 

这样就可以匹配到查询结果。

2.查询以某个字母开头的集合

mongodb语法:

db.UserInfo.find({userName :/^A/})

nodejs中写法:

router.post(‘/like_article_search‘, (req,res) => {
    let searchValue = req.body.value
    console.log(searchValue)
    var str="^.*"+searchValue+".*$"
    var reg = new RegExp(str)

    Article.find({"title":{$regex:reg,$options: ‘i‘}}, (err, data) => { // {"title": /searchValue/} $options:‘i‘ 表示忽略大小写
        if(err) {
            console.log(err)
            return res.status(500).json({
                result: 1,
                error_info: err.message
            })
        }
        console.log(data)
        let length = data.length
        return res.status(200).json({
            result: 0,
            count: length,
            searchArticle: data
        })
    })
})

3.多条件模糊查询

使用$or 语法。

多字段匹配,title、categroy、lable中包含查询关键词的都进行匹配

//模糊查询
router.post(‘/like_article_search‘, (req,res) => {
    let searchValue = req.body.value
    // console.log(searchValue)
    // var str=".*"+searchValue+".*$"
    // var reg = new RegExp(str)
    var reg = new RegExp(searchValue);
    var _filter = {
    //多字段匹配
        $or: [
            {‘title‘: {$regex: reg}},
            {‘categroy‘: {$regex: reg}},
            {‘lable‘: {$regex: reg}},
        ]
    }

    Article.find(_filter, (err, data) => { // {"title": /searchValue/} $options:‘i‘ 表示忽略大小写
        if(err) {
            console.log(err)
            return res.status(500).json({
                result: 1,
                error_info: err.message
            })
        }
        console.log(data)
        let length = data.length
        return res.status(200).json({
            result: 0,
            count: length,
            searchArticle: data
        })
    })
})

这样就可以实现。还可以通过某个字段对搜索结果进行降序或升序排列。

 

以上是关于Mongodb数据库的模糊搜索的主要内容,如果未能解决你的问题,请参考以下文章

基于mongodb的搜索分页

sql 模糊搜索无输入参数时查询所有

请教下mongo的模糊搜索中字段有特殊符号怎么办

input 模糊搜索

ES实现模糊搜索

C# combobox 模糊搜索。