当前位置: 首页 > news >正文

Elasticsearch2.x 同义词设置

 elasticsearch自身支持本地同义词,使用远程词库需要使用插件,两种方式使用方法如下:

一  本地同义词库

官方地址:https://www.elastic.co/guide/en/elasticsearch/reference/5.0/analysis-synonym-tokenfilter.html

安装好elasticsearch和elasticsearch-analysis-ik分词器分词器后,再配置同义词;elasticsearch 自身自带的有一个名为 synonym 同义词的 filter,需要我们在自定义分析器的时候指定使用该filter;步骤如下:

例1
1)新建同义词文件:首先要在es的elasticsearch-2.3.3/config目录下面,存放synonyms.txt, synonyms.txt 编码格式为’utf-8’;在文件里写入同义词配置:

西红柿, 番茄
马铃薯, 土豆
有两种写法:
a,b => c a,b,c

第一种在分词的时候,a,b都会解析成为c,然后把c存入索引中
第二种在分词的时候,有a的地方,都会解析成a,b,c,把a,b,c存入索引中
第一种方法相比之下有个主词,比较省索引。

2)新建索引,自定义分析器:

/atest/   post

{
  "settings": {
    "analysis": {
      "analyzer": {
        "customsynonym": {
          "tokenizer": "whitespace",
          "filter": [
            "mysynonym"
          ]
        }
      },
      "filter": {
        "mysynonym": {
          "type": "synonym",
          "synonyms_path": "analysis/synonym.txt",
          "ignore_case": true
        }
      }
    }
  },
  "mappings": {
    "product": {
      "properties": {
        "firstname": {
          "type": "string",
          "index": "analyzed",
          "analyzer": "customsynonym" 
} } } } }

3 测试:

http://192.168.60.60:xxxx/atest/_analyze?text=土豆&analyzer=customsynonym

  结果:

{
  "tokens": [
    {
      "token": "土豆",
      "start_offset": 0,
      "end_offset": 2,
      "type": "word",
      "position": 0
    },
    {
      "token": "马铃薯",
      "start_offset": 0,
      "end_offset": 2,
      "type": "SYNONYM",
      "position": 0
    }
  ]
}

例2 也可以不在索引中定义,在/config/elasticsearch.yml es的配置文件中定义改配置,同时同义词也可以结合ik分词器使用:

1)跟上面一样新建同义词文件,加入同义词数据;

2)在es配置文件elasticsearch.yml中最后面加入如下配置

index:
  analysis:
    analyzer:
      ik_syno:
          type: custom
          tokenizer: ik_max_word
          filter: [my_synonym_filter]
      ik_syno_smart:
          type: custom
          tokenizer: ik_smart
          filter: [my_synonym_filter]
    filter:
      my_synonym_filter:
          type: synonym
          synonyms_path: analysis/synonym.txt

以上配置定义了 ik_syno 和 ik_syno_smart 这两个新的 analyzer,分别对应 IK 的 ik_max_word 和 ik_smart 两种分词策略。根据 IK 的文档,二者区别如下:
● ik_max_word:会将文本做最细粒度的拆分,例如「中华人民共和国国歌」会被拆分为「中华人民共和国、中华人民、中华、华人、人民共和国、人民、人、民、共和国、共和、和、国国、国歌」,会穷尽各种可能的组合;
● ik_smart:会将文本做最粗粒度的拆分,例如「中华人民共和国国歌」会被拆分为「中华人民共和国、国歌」;
ik_syno 和 ik_syno_smart 两个自定义分析器 都会使用 synonym filter 实现同义词转换。

可以直接使用 http://192.168.60.60:xxxx/_analyze?text=土豆&analyzer=customsynonym 测试,在指定mapping时,可以使用一定的策略,例如部分字段指定自定义的分析器ik_syno 或 ik_syno_smart 他们都是兼容同义词的,部分字段不指定,而使用默认的ik分词器等等

http://blog.csdn.net/yusewuhen/article/details/50685685#comments
 
 

二 动态同义词配置(远程词库)

   本地同义词设置只能读取本地同义词文件,如果我们要动态热更新同义词,并配置远程同义词词库需要使用到elasticsearch-analysis-dynamic-synonym插件,官方地址:https://github.com/bells/elasticsearch-analysis-dynamic-synonym

1 选择合适的包:

找到适合Elasticsearch版本的elasticsearch-analysis-dynamic-synonym插件,如果没有找到适合的版本,可以找临近的版本,通过修改配置文件的版本号来解决兼容性

例如我的es是2.3.3的,没有找到对应es2.3.3的包,就下载2.3.0的包,编译后修改plugin-descriptor.properties文件的配置,将2.3.0修改为2.3.3:

 

2 安装步骤:

1) 下载包,并在包的目录执行

2)  mvn package   //编译

3)  将编译成功后会生成target目录,将target/releases/elasticsearch-analysis-dynamic-synonym-{version}.zip 文件copy并解压到到es的plugins目录: plugins/dynamic-synonym,

路径地址如图:

注意:实际解压出来的文件比上面要多,由于个别文件与之前安装的IK插件里的文件冲突,故删掉这里的冲突的文件。


3 新建远程同义词库:http://10.10.110.201:1111/dics/synonym.txt  ,注意远程词库必须是utf-8格式

4 结合ik分词器,使用同义词分词器 自定义分析器

最终既读取了ik词库里的词语,又可以使用同义词功能

测试:

http://192.168.60.60:xxxx/atest/_analyze?text=土豆&analyzer=my_synonym

 

{
  "tokens": [
    {
      "token": "土豆",
      "start_offset": 0,
      "end_offset": 2,
      "type": "CN_WORD",
      "position": 0
    },
    {
      "token": "马铃薯",
      "start_offset": 0,
      "end_offset": 2,
      "type": "SYNONYM",
      "position": 0
    },
    {
      "token": "",
      "start_offset": 1,
      "end_offset": 2,
      "type": "CN_WORD",
      "position": 1
    }
  ]
}

官方介绍的写法: 

 

{
    "index" : {
        "analysis" : {
            "analyzer" : {
                "synonym" : {
                    "tokenizer" : "whitespace",
                    "filter" : ["remote_synonym"]
               }
            },
            "filter" : {
                "remote_synonym" : {
                    "type" : "dynamic_synonym",
                    "synonyms_path" : "http://host:port/synonym.txt",
                    "interval": 30
                },
                "local_synonym" : {
                    "type" : "dynamic_synonym",
                    "synonyms_path" : "synonym.txt"
                },
            }
        }
    }
}

说明: synonyms_path 是必须要配置的,根据它的值是否是以http://开头来判断是本地文件,还是远程文件。

interval 非必须配置的,默认值是60,单位秒,表示间隔多少秒去检查同义词文件是否有更新。

ignore_case 非必须配置的, 默认值是false。

expand 非必须配置的, 默认值是true。

format 非必须配置的, 默认值是空字符串, 如果为wordnet,则表示WordNet结构的同义词。

热更新同义词说明

  1. 对于本地文件:主要通过文件的修改时间戳(Modify time)来判断是否要重新加载。
  2. 对于远程文件:synonyms_path 是指一个url。 这个http请求需要返回两个头部,一个是 Last-Modified,一个是 ETag,只要有一个发生变化,该插件就会去获取新的同义词来更新相应的同义词。

注意: 不管是本地文件,还是远程文件,编码都要求是UTF-8的文本文件

 

 es的自定义分析器介绍: http://www.cnblogs.com/shaner/p/6340925.html

es分词器插件介绍: http://www.cnblogs.com/shaner/p/5663588.html

 

 nest的实现代码:

        /// <summary>
        /// 生成包含拼音分词和同义词功能的mapping
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="indexName"></param>
        public static ICreateIndexResponse AddSynonymsIKPYMapping<P>(string indexName) where P : class
        {
            var pinYinTokenizer = new PinYinTokenizer();
            var pinYinTF = new PinYinTF();

            var iktokenizer = new Iktokenizer();
            var remote_synonymtf = new Remote_synonymTF();
            ICreateIndexRequest descriptor = new CreateIndexDescriptor(indexName)
            .Settings(s => s
                .Analysis(a => //自定义分析器
                    a.Tokenizers(ts => ts.UserDefined("ik", iktokenizer)
                         .UserDefined("pinyintoken", pinYinTokenizer))
                     .TokenFilters(tf => tf.UserDefined("remote_synonym", remote_synonymtf)
                         .UserDefined("pinyintf", pinYinTF))
                     .Analyzers(c => c.Custom("synonymikanalyzer", f => f.Tokenizer("ik").Filters("remote_synonym"))
                         .Custom("pinyinanalyzer", f => f.Tokenizer("pinyintoken").Filters("pinyintf"))) //设置ik&同义词自定义的分析器
                    )
            ).Mappings(ms => ms
                .Map<P>(m => m.AutoMap())
            );
            var ir = ESHelper.GetInstance().GetElasticClient().CreateIndex(descriptor);
            return ir;

        }
View Code
    class Iktokenizer : ITokenizer
    {
        public string Type
        {
            get { return "ik"; }
        }

        public string Version
        {
            get
            {
                return "";
            }
            set
            {
                throw new NotImplementedException();
            }
        }
    }

    public class Remote_synonymTF: ITokenFilter
    {

        public string Type
        {
            get { return "dynamic_synonym"; }
        }

        /// <summary>
        /// 远程词库地址
        /// </summary>
        public string synonyms_path {
            get { return AppConfig.SynonymsPath; }
        }
        /// <summary>
        /// 词库刷新时间 s
        /// </summary>
        public string interval
        {
            get { return "5"; }

        }
        /// <summary>
        /// 
        /// </summary>
        public string Version
        {
            get
            {
                return "";
            }
            set
            {
                throw new NotImplementedException();
            }
        }
    }
View Code
    /// <summary>
    /// 自定义拼音分词器
    /// </summary>
    public class PinYinTokenizer : ITokenizer
    {


        public string Type
        {
            get { return "pinyin"; }
        }

        public string Version
        {
            get
            {
                return string.Empty;
            }
            set
            {
                throw new NotImplementedException();
            }
        }

        public string first_letter
        {
            get { return "prefix"; } //开启前缀匹配
        }

        //public string padding_char
        //{
        //    get { return " "; }
        //}

        public bool keep_full_pinyin
        {
            get { return true; }

        }

    }
    /// <summary>
    /// 自定义拼音词元过滤器
    /// </summary>
    public class PinYinTF : ITokenFilter
    {
        /// <summary>
        /// 连词过滤器
        /// </summary>
        public string Type
        {
            get { return "nGram"; }
        }

        public string Version
        {
            get
            {
                return "";
            }
            set
            {
                throw new NotImplementedException();
            }
        }

        public int min_gram
        {
            get
            {
                return 1;
            }
        }
        public int max_gram
        {
            get
            {
                return 10;
            }
        }
    }
View Code

 

转载于:https://www.cnblogs.com/shaner/p/6428961.html

相关文章:

  • [ANT] 项目中应用ANT
  • maven中对jsp预编译方法
  • vi 界面复制粘贴操作
  • js数据类型判断和数组判断
  • 使用Response.redirect重定向到带锚点页面的技巧
  • ASP.NET中的OutOfMemoryException
  • jquery.min.map 404 (Not Found)出错的原因及解决办法
  • 字符压缩题目
  • Monad B3 is Released!!
  • 通过内推来应聘职位,你的体验是怎样的?
  • 关注朱令--十年前铊中毒的女孩(本文转自http://www8.tianya.cn)
  • ASP.NET程序中常用代码汇总(五)
  • POJ 2154 Color [Polya 数论]
  • 今天也申请了一个博克, 打算好好整理一下
  • HTML5 本地数据库SQLLite
  • 【翻译】Mashape是如何管理15000个API和微服务的(三)
  • android 一些 utils
  • DOM的那些事
  • Invalidate和postInvalidate的区别
  • Rancher-k8s加速安装文档
  • SpringBoot 实战 (三) | 配置文件详解
  • springMvc学习笔记(2)
  • 分布式任务队列Celery
  • 基于HAProxy的高性能缓存服务器nuster
  • 少走弯路,给Java 1~5 年程序员的建议
  • 吐槽Javascript系列二:数组中的splice和slice方法
  • 小程序开发中的那些坑
  • 远离DoS攻击 Windows Server 2016发布DNS政策
  • No resource identifier found for attribute,RxJava之zip操作符
  • ​力扣解法汇总946-验证栈序列
  • !!【OpenCV学习】计算两幅图像的重叠区域
  • (1)bark-ml
  • (1)Map集合 (2)异常机制 (3)File类 (4)I/O流
  • (Redis使用系列) Springboot 使用redis实现接口Api限流 十
  • (ZT) 理解系统底层的概念是多么重要(by趋势科技邹飞)
  • (四)汇编语言——简单程序
  • (自用)learnOpenGL学习总结-高级OpenGL-抗锯齿
  • .mysql secret在哪_MySQL如何使用索引
  • .NET 4 并行(多核)“.NET研究”编程系列之二 从Task开始
  • .Net Core/.Net6/.Net8 ,启动配置/Program.cs 配置
  • .net mvc actionresult 返回字符串_.NET架构师知识普及
  • .Net6 Api Swagger配置
  • .sh 的运行
  • /proc/stat文件详解(翻译)
  • [ linux ] linux 命令英文全称及解释
  • [.net] 如何在mail的加入正文显示图片
  • [AI]文心一言出圈的同时,NLP处理下的ChatGPT-4.5最新资讯
  • [C#小技巧]如何捕捉上升沿和下降沿
  • [CF543A]/[CF544C]Writing Code
  • [codevs] 1029 遍历问题
  • [DP 训练] Longest Run on a Snowboard, UVa 10285
  • [EWS]查找 文件夹
  • [J2ME]url请求返回参数非法(java.lang.illegalArgument)
  • [Java] 什么是IoC?什么是DI?它们的区别是什么?
  • [Java基础]—JDBC