当前位置:首页 > ELK > 正文内容

elasticsearch中分析器的原理和使用

phpmianshi2年前 (2019-07-18)ELK572

概念

分析(analysis)机制用于进行全文文本(Full Text)的分词,以建立供搜索用的反向索引。


原理

分析器的工作过程大概分成两步:

  1. 分词(Tokenization):根据停止词把文本分割成很多的小的token,比如the quick fox会被分成thequickfox,其中的停止词就是空格,还有很多其他的停止词比如&或者#,大多数的标点符号都是停止词

  2. 归一化(Normalization):把分隔的token变成统一的形式方便匹配,比如下面几种

    • 把单词变成小写,Quick会变成quick

    • 提取词干,foxes变成fox

    • 合并同义词,jumpleap是同义词,会被统一索引成jump

Elasticsearch自带了一个分析器,是系统默认的标准分析器,只对英文语句做分词,中文不支持,每个中文字都会被拆分为独立的个体。

示例

想要知道某个解析器的分析结果,可以直接在ES里面进行分析,执行下面的语句就行了:

POST /_analyze
{
  "analyzer": "standard",
  "text": "1 Fire's foxes"
}

返回的结果是:

{
  "tokens" : [
    {
      "token" : "1",
      "start_offset" : 0,
      "end_offset" : 1,
      "type" : "<NUM>",
      "position" : 0
    },
    {
      "token" : "fire's",
      "start_offset" : 2,
      "end_offset" : 8,
      "type" : "<ALPHANUM>",
      "position" : 1
    },
    {
      "token" : "foxes",
      "start_offset" : 9,
      "end_offset" : 14,
      "type" : "<ALPHANUM>",
      "position" : 2
    }
  ]
}

返回的tokens内部就是所有的解析结果,token表示解析的词语部分,start_offsetend_offset分别表示token在原text内的起始和终止位置,type表示类型,position表示这个token在整个tokens列表里面的位置。


如果想在某个索引下进行分词

POST /my_index/_analyze
{    
"analyzer": "standard",    
"field": "name",    
"text": "text文本"
}


es内置分词器

  • standard:默认分词,单词会被拆分,大小会转换为小写。

  • simple:按照非字母分词。大写转为小写。

  • whitespace:按照空格分词。忽略大小写。

  • stop:去除无意义单词,比如the/a/an/is…

  • keyword:不做分词。把整个文本作为一个单独的关键词


如何让ES的某个字段既能支持精确匹配查找,也能支持模糊检索

将字段的mapping设置为如下这种即可

"properties": {
               "name": {
                  "type": "text",
                  "fields": {
                     "keyword": {
                        "type": "keyword",
                        "ignore_above": 256
                     }
                  }
               }

ElasticSearch 5.0以后,string字段被拆分成两种新的数据类型:
Text:会分词,然后根据分词后的内容建立倒排索引(反向索引)
不支持聚合
keyword:不进行分词,直接直接根据字符串内容建立倒排索引(反向索引)
支持聚合

ElasticSearch字符串将默认被同时映射成text和keyword类型,将会自动创建上面的动态映射(dynamic mappings),比如上面的name字段,不做任何配置ES就会默认给他映射成两个类型。


text格式的数据和keyword格式的数据在存储和索引的时候差别比较大。keyword会直接被当成整个字符串保存在文档里面,而text格式数据,需要经过分析器解析之后,转化成结构化的文档再保存起来。比如对于the quick fox字符串,如果使用keyword类型,保存直接就是the quick fox,使用the quick fox作为关键词可以直接匹配,但是使用the或者quick就不能匹配;但是如果使用text保存,那么分析器会把这句话解析成thequickfox三个token进行保存,使用the quick fox就无法匹配,但是单独用thequickfox三个字符串就可以匹配。所以对于text类型的数据的搜索需要格外注意,如果你的搜索词得不到想要的结果,很有可能是你的搜索语句有问题。


analyzer 分词器(重点)和 search_analyzer

analyzer: 插入文档时,将text类型的字段做分词然后插入倒排索引

search_analyzer:在查询时,先对要查询的text类型的输入做分词,再去倒排索引搜索

在索引时,只会去看字段有没有定义analyzer,有定义的话就用定义的,没定义就用ES预设的

在查询时,会先去看字段有没有定义search_analyzer,如果没有定义,就去看有没有analyzer,再没有定义,才会去使用ES预设的

PUT /my_index
{
  "mappings": {
    "properties": {
      "text": { 
        "type": "text",
        "fields": {
          "english": { 
            "type":     "text",
            "analyzer": "english",
            "search_analyzer": "english" 
          }
        }
      }
    }
  }
}
#使用_analyze  测试分词器
GET my_index/_analyze 
{
  "field": "text",
  "text": "The quick Brown Foxes."
}
 
GET my_index/_analyze 
{
  "field": "text.english",
  "text": "The quick Brown Foxes."
}

中文分词


下载:Github:https://github.com/medcl/elasticsearch-analysis-ik

这里需要选择和你的es版本一致的ik。我的是7.5.1

解压安装:

unzip elasticsearch-analysis-ik-7.5.1.zip -d /usr/local/elasticsearch-7.5.1/plugins/ik

重启生效


ik_max_word 和 ik_smart 什么区别?

  • ik_max_word: 会将文本做最细粒度的拆分,比如会将“中华人民共和国国歌”拆分为“中华人民共和国,中华人民,中华,华人,人民共和国,人民,人,民,共和国,共和,和,国国,国歌”,会穷尽各种可能的组合,适合 Term Query;

  • ik_smart: 会做最粗粒度的拆分,比如会将“中华人民共和国国歌”拆分为“中华人民共和国,国歌”,适合 Phrase 查询。


自定义中文词库


1.进入IKAnalyzer.cfg.xml 配置如下

<!--用户可以在这里配置自己的扩展字典 -->
	<entry key="ext_dict">custom.dic</entry>

2.保存后 在同级目录下建立custom.dic

[esuser@localhost config]$  cat custom.dic 
6神
牛皮


3.重启es

4.测试

POST /_analyze
{
	"analyzer": "ik_smart",
	"text": "6神牛皮"
}
# 返回

{
	"tokens": [{
			"token": "6神",
			"start_offset": 0,
			"end_offset": 2,
			"type": "CN_WORD",
			"position": 0
		},
		{
			"token": "牛皮",
			"start_offset": 2,
			"end_offset": 4,
			"type": "CN_WORD",
			"position": 1
		}
	]
}





版权声明:本文由PHP面试资料网发布,如需转载请注明出处。
分享给朋友:

相关文章

block b-tree.jpg

elasticsearch中字符串类型text vs keyword的选择

关于ES字符串类型的选择ElasticSearch 5.0以后,string类型有重大变更,移除了string类型,string字段被拆分成两种新的数据类型: text用于全文搜索的,而ke...

elasticsearch用于html去标签化搜索

场景elasticsearch用于html去标签化搜索:即在Index的时候忽略html tag,同时又存储了完整的html,在使用的时候可以正常读出来。示例假设我们给content字段自定义anal...

elasticsearch高亮搜索highlight

概念我们在浏览器上搜索文本时,发现我们输入的关键字有高亮显示,查看html源码就知道,高亮的部分是加了<em>标签的,ES也支持高亮搜索这种操作的,并且在返回的文档中自动加了<em&...

elasticsearch中forcemerge清除文件占用的磁盘空间

elasticsearch中forcemerge清除文件占用的磁盘空间

背景最近发现es占用的磁盘存储大小一直在增加,本来1mb的东西,隔了1-2天达到100mb多,如下分析    elasticsearch是建立在Apache Lucene...

elasticsearch中mapping全解实战

Mapping简介#mapping 是用来定义文档及其字段的存储方式、索引方式的手段,例如利用mapping 来定义以下内容:哪些字段需要被定义为全文检索类型哪些字段包含number、dat...

使用logstash-input-jdbc同步mysql到es

数据同步方式全量同步与增量同步全量同步是指全部将数据同步到es,通常是刚建立es,第一次同步时使用。增量同步是指将后续的更新、插入记录同步到es。(删除记录没有办法同步,只能两边执行自己的删除命令)常...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。