• 对MongoDB中的数据进行搜索(1)


    由于大量的数据使用MongoDB作为数据库进行存储,现在需要对外提供文本搜索功能,在实践工程中,调研并尝试了多种方案,在本文中做个记录。

    1、使用正则表达式

    即使用find("textField":/搜索文本/}的方式对文本字段进行包含匹配。

    这种方法的好处在于不需要进行额外的操作,现在常用的MongoDB服务器版本都能够支持,非常方便。

    但是同时,缺点也非常明显,每次搜索必须遍历所有的数据,消耗的时间与数据量成正比,且基本无法进行优化。在大数据量情况下每次搜索小号的时间太长,可能无法接受。

    2、分词存储

    基本的步骤如下:

    1、使用分词引擎对目标文本字段,例如textField进行分词

    2、将分词的结果的每个词按照数组的形式存储在一个新的字段,例如searchField中

    3、对searchField建立索引

    4、搜索时,对请求串进行同样的分词,并将分词结果作为参数进行find({ searchField: {$all: splittedTextArray} })

    这种方法的好处在于,适用于各个版本的MongoDB,同时基于索引和MongoDB对于数组的专门优化,在一定数据量的情况下速度也还可以

    如果要使用这种方法,需要在新数据入库时进行处理

    功能上比较简单,很多搜索常用的需求无法实现,效率也比不上专业的搜索引擎。可以作为一种无法增加组件时的参考方案。

    3、使用MongoDB自带的文本搜索功能

    MongoDB在较早的版本中就已经将文本搜索功能作为实验性功能加入,当时需要使用runCommand作为系统命令进行调用。

    在后来的版本中作为正式的功能引入,直接就可以使用find({"$text":{"$search":"搜索文本"})进行搜索

    在搜索之前,需要对文本字段建立索引:

    db.coll.createIndex( { textField: "text" } )

    对于一个集合,只能建立一个索引,但是一个索引中可以包含多个字段

    文本搜索的参数有如下几个:

    $search: <string>,
    $language: <string>,
    $caseSensitive: <boolean>,
    $diacriticSensitive: <boolean> 

    $search后面的关键词可以有多个,并且可以使用一些符号表示与或非的关系

    使用$caseSensitive设置是否区分大小写,$language指示搜索的语言类型

    $diacriticSensitive设置是否区别发音符号,例如,CAFÉ于Café是同一语义,只是重音不一样。

    并且在结果中,可以使用{score:{$meta:"textScore"}来获得相似度

    不过,只有在Mongodb 3.2之后的企业版中才开始加入了对中文的支持,之前或者社区的版本在建立全文索引时会自动过滤中文字符。

    在Mongodb 3.2企业版中,对中文建立全文索引后,默认使用的是与英文同样的分词规则,即以空格与符号作为词与词之间分隔的界限。

    所以,当使用“福尔摩斯”作为搜索词时,无法搜索到“福尔摩斯探案全集”,只能搜索到类似“福尔摩斯(1)”之类的结果

    如果想解决这种情况,可以有两种方法:

    一、在存储文本时,自行先对该文本进行分词处理,将需要搜索的文本加上空格即可

    二、为MongoDB添加中文分词的支持

    MongoDB企业版集成了基础技术Rosette 语义平台(RLP)根据语言来进行正规化、分词、断句、词干和分词。所以,可以使用RLP来实现对中文分词的支持。

    如果想在MongoDB中使用RLP,MongoDB需要一个RLP基础语义组件的许可证。具体如何获得RLP的许可证,需要联系basistech公司。

    当从basistech公司的邮件中获取了RLP证书文件(rlp-license.xml)后,解压拷贝到对应的目录中

    <BT_ROOT>/rlp/rlp/licenses

    然后使用参数指定该目录,重启MongoDB即可

    --basisTechRootDirectory=<BT_ROOT>

  • 相关阅读:
    jq 切换功能toggle
    打开控制台F12弹出弹窗
    CSS解决无空格太长的字母,数字不会自动换行的问题
    微信公众号页面无法唤起输入框
    别人遇到的两条前端面试题
    在HTML打开已安装的App,未安装跳转到对应的下载链接
    promise的使用
    特殊的json对象转数组,最合成新的json数据
    Rem兼容知多少?
    parseInt的结果看不懂,请看我分析
  • 原文地址:https://www.cnblogs.com/ruizhang3/p/6624645.html
Copyright © 2020-2023  润新知