美文网首页
ES - 中文分词及高亮搜索

ES - 中文分词及高亮搜索

作者: 君剑 | 来源:发表于2017-09-05 16:45 被阅读776次

    包括内容:

    IK分词组件的添加和配置

    索引建立及高亮搜索示例

    添加自定义分词的测试

    版本: 

    ES - 2.4.5, IK - 1.10.5 
    ps: 5.0的版本, 配置和验证代码都不是太一样, 以下应该只适用于2.x版本

    IK Analyzer是一个开源的, 基于java语言开发的轻量级的中文分词工具包, 应该是目前比较公认的适合ES的中文分词方案, 因为它默认实现了针对luence的优化. 下面会先介绍安装配置方法, 再介绍应用. 

    Analyzer:ik_smart,ik_max_word, Tokenizer:ik_smart,ik_max_word

    这里假设我们已经配置好了ES集群 [这个确实很简单, 因为es的默认配置就已经很好]

    推荐使用rpm的安装方式:

    一 下载对应的IK版本
    https://github.com/medcl/elasticsearch-analysis-ik

    二 下载pre-build, 或者自行编译

    工程是pom, 需要安装maven,
    git clone https://github.com/medcl/elasticsearch-analysis-ik
    cd elasticsearch-analysis-ik
    git checkout tags/{version}
    mvn clean
    mvn compile
    mvn package

    我其实是直接下载的pre-build, elasticsearch-analysis-ik-1.10.5.zip

    三 配置

    First, 解压elasticsearch-analysis-ik-1.10.5.zip, 拷贝到plugins/analysis-ik下, 如果是rpm安装的, 则对应的目录为/usr/share/elasticsearch/plugins/analysis-ik

    Second, 修改elasticsearch的配置文件,指定IK为分词工具。打开/etc/elasticsearch/elasticsearch.yml, 最后添加 [这不应该也不用做, 我有两个节点没做也是没问题的, 所以官方文档是对的]:

        index.analysis.analyzer.default.type: ik

    Last, 词典. 看到很多人写的安装引导都提到了将词典拷贝到es的config目录, 亲测这一步是不需要的. 

    验证: 最好还是用浏览器直接验证, 命令行的话还需要处理编码问题

    (虽然, 官方说明说在某个索引下调用接口测试, 如果是单点测试的话, 其实没什么差异, 但是要是集群的话指定的index决定了在哪个节点执行)

    http://localhost:9200/ik_index/_analyze?text=我是中国人&tokenizer=ik&pretty=true
    http://localhost:9200/_analyze?analyzer=ik&pretty=true&text=我是中国人

    analyzer目前支持两种, ik_max_word和ik_smart, 他们的区别在于分词的粒度

    ik_max_word: "我是中国人" --> "我, 中国人, 中国, 国人"

    ik_smart: "我是中国人" --> "我, 中国人"

    官方文档分词测试验证: 

    PS: 个人比较喜欢kopf这个插件, 简洁, 清晰, 

    1 创建ik_index

    PUT http://localhost:9200/ik_index

    2 创建mapping

    POST http://localhost:9200/ik_index/fulltext/_mapping -d'
    {
    "fulltext":
          {"_all": {
             "analyzer": "ik_max_word",
             "search_analyzer": "ik_max_word",
             "term_vector": "no","store": "false"
          },
            "properties": {
                   "content": {
                        "type": "string",
                        "store": "no",
                        "term_vector": "with_positions_offsets",
                        "analyzer": "ik_max_word",
                        "search_analyzer": "ik_max_word",
                        "include_in_all": "true",
                        "boost": 8}}
    }}'

    3 index some docs

    curl -XPOST http://localhost:9200/ik_index/fulltext/1 -d'{"content":"美国留给伊拉克的是个烂摊子吗"}'

    curl -XPOST http://localhost:9200/ik_index/fulltext/2 -d'{"content":"公安部:各地校车将享最高路权"}'

    curl -XPOST http://localhost:9200/ik_index/fulltext/3 -d'{"content":"中韩渔警冲突调查:韩警平均每天扣1艘中国渔船"}'

    curl -XPOST http://localhost:9200/ik_index/fulltext/4 -d'{"content":"中国驻洛杉矶领事馆遭亚裔男子枪击 嫌犯已自首"}'

    4 query with highlighting

    curl -XPOST http://localhost:9200/ik_index/fulltext/_search  -d'
    {
    "query" :{ "term" : { "content" : "中国" }},
    "highlight" : {"pre_tags" : ["", ""],
    "post_tags" : ["", ""],
    "fields" : {"content" : {}}}
    }'

    result:

    Dictionary Configuration:

    IKAnalyzer.cfg.xml can be located at{conf}/analysis-ik/config/IKAnalyzer.cfg.xml or {plugins}/elasticsearch-analysis-ik-*/config/IKAnalyzer.cfg.xml

    热更新 IK 分词使用方法

    目前该插件支持热更新 IK 分词,通过上文在 IK 配置文件中提到的如下配置

    其中location是指一个 url,比如http://yoursite.com/getCustomDict,该请求只需满足以下两点即可完成分词热更新。

    1. 该 http 请求需要返回两个头部(header),一个是Last-Modified,一个是ETag,这两者都是字符串类型,只要有一个发生变化,该插件就会去抓取新的分词进而更新词库。

    2. 该 http 请求返回的内容格式是一行一个分词,换行符用\n即可。

    满足上面两点要求就可以实现热更新分词了,不需要重启 ES 实例。

    可以将需自动更新的热词放在一个 UTF-8 编码的 .txt 文件里,放在 nginx 或其他简易 http server 下,当 .txt 文件修改时,http server 会在客户端请求该文件时自动返回相应的 Last-Modified 和 ETag。可以另外做一个工具来从业务系统提取相关词汇,并更新这个 .txt 文件。

    添加分词测试:

    公司名称叫小鱼易连, 小鱼是可以被识别成一个词的, 但是易连就不认了, 效果如下

    localhost:9200/_analyze?analyzer=ik&pretty=true&text=小鱼易连

    这可不是我期望的, 用户在搜产品文档的时候输入"易连"找不到结果可不行, 其实很简单, 有两种方法:

    一个是根据上面提到的热更新方法, 通过插件自动抓取扩展词典的变化更新词库. 

    另外一个, 我们可以快速验证, 通过更改config/custom下的mydict.dic, 在文件结尾添加"易连"即可, 不过需要重启服务加载词库.效果如下:

    可以看到, 文档6的得分明显高于文档5, 您可以用5秒钟思考一下为什么.

    及时只搜索"易连", 文档6同样相关度更高

    答案是, 文档6在索引时, 添加了"小鱼易连"这个分词, 关于这个评分, 因为会做一个站内搜索功能, 以后会单独分享一次, 包括高亮的介绍.

    相关文章

      网友评论

          本文标题:ES - 中文分词及高亮搜索

          本文链接:https://www.haomeiwen.com/subject/gkkujxtx.html