Elasticsearch 使用同义词 一
阅读原文时间:2021年04月22日阅读:1

elasticsearch 使用同义词

先说一下,为什么使用同义词。任何一种技术的实现,都需要为我们的使用场景服务:下面就是我将要实现功能的使用场景

需求一:要获取一个词汇的同义词。比如输入:美女   获取结果:女性 美女 妇女 女孩 等…….

需求二:要获取一个词汇的同义汇总词。比如输入:美女,妇女,女性,女孩 获取结果:女性

解析技术的信息
// 精确映射同义词,【阿迪】、【阿迪达斯】和【adidasi】的token将会转换为【Adidas】存入倒排索引中
阿迪, 阿迪达斯, adidasi => Adidas

// 对等同义词
// 当expand为true时,当出现以下任何一个token,三个token都会存入倒排索引中
// 当expand为false时,当出现以下任何一个token,第一个token也就是【Nike】会存入倒排索引中
Nike, 耐克, naike

部分信息参考:参考来源  

实现技术

ElasticSearch 5.1.1 + IK + synonym 

使用环境

安装插件

下载对应的elasticsearch-analysis-dynamic-synonym-5.1.1.zip, 解压到本地的elasticsearch/plugins目录下, 重新启动es

  • 第一种方式本地文件配置

    说明:

  • 对于本地文件:主要通过文件的修改时间戳(Modify time)来判断是否要重新加载

  • 在elasticsearch/config目录下,建立analysis目录, 并在analysis目录下放入synonym.txt, 在文件首行加入下面一行同义词,来进行测试。加入的行信息:

  • 美女,女性,女孩,妇女

    es设置索引和自定义解析器,用 kibana 执行哈

  • PUT /megacorp
    {
    "mappings": {
    "customerset": {
    "properties": {
    "name":{
    "type": "text",
    "analyzer": "ik-index", //指定索引时候用的解析器
    "search_analyzer": "ik-smart" //指定搜索时候用的解析器
    }
    }
    }
    }
    ,
    "settings": {
    "analysis": {
    "filter": {
    "local_synonym" : {
    "type" : "dynamic_synonym",
    "synonyms_path" : "analysis/synonym.txt"
    }
    },
    "analyzer": {
    "ik-index": {
    "type": "custom",
    "tokenizer": "ik_max_word",
    "filter": [
    "local_synonym" //对同义词进行了过滤
    ]
    },
    "ik-smart": {
    "type": "custom",
    "tokenizer": "ik_smart",
    "filter": [
    "local_synonym"
    ]
    }
    }
    }
    }
    }

    设置好后,可以用以下命令查看,同义词是否配置成功。本示例均使用Kibana测试,用Postman的各位自己加域名即可

  • GET /megacorp/_analyze
    {
    "analyzer": "ik-index",
    "text": "美女"
    }

    正确分词以及同义词综合返回结果如下:截图

  • 我们要实现搜索一个词汇只返回一个词汇,加入一行配置:

  • 西红柿,番茄,土豆,马铃薯 => 土豆 ;

  • 注意:词库内的词,必须在分词词库中存在,下一章我会告知怎么配置

    搜索,使用如下命令:

  • GET /megacorp/_analyze
    {
    "analyzer": "ik-index",
    "text": "马铃薯"
    }

    结果:图例

  • 上面的结果有彩蛋:【;】这也是一个汇总,为什么呢:因为汇总可以是多个,且多个是以空格分割

  • 上面的一种实现方式是使用写入文本的方式,但是我们程序实际运行的时候可会动态的新增同义词,比如说:我的机器学习,能自动归纳词汇然后汇总成同义词。这个时候我们需要使用接口实现。

  • 还记得上面定义的时候我创建了一个 customerset 的mapping:这个时候我要用到了,需要大家有一定的ElasticSearch  的使用经验哈,我们开始:

  • ------------ 》》》》》》》》》》》

  • PUT /megacorp/mysynonym/10
    {
    "name" : "Z型钢"
    }

    PUT /megacorp/mysynonym/11
    {
        "name" : "S型钢"
    }
    
    PUT /megacorp/mysynonym/12
    {
        "name" : "H型钢"
    }
    
    PUT /megacorp/mysynonym/13
    {
        "name" : "钢轨"
    }

    查询语句:

  • GET /megacorp/mysynonym/_search
    {
    "query":{
    "match": {
    "name": "H型钢"
    }
    }
    }

  • 写入文档的方式则是依靠自动匹配同义词,这个功能其实才是更好用。