做了小写、去掉特殊字符等操作】
简单分词器simple analyzer:i
,am
,a
,little,boy
,i
,have
,dogs
,long
,distance
,html
,html
【这个分词器做了小写、去掉特殊字符和数字等操作】
空格分词器whitespace analyzer:I
,am
,a
,little
,boy,I
,have
,5$.dogs,long-distance,<html></html>
【根据空格分词】
英文分词器英文分词器english::i
,am
,littl
,boi
,i
,have
,5
,dog
,long
,distanc
,html
,html
【语言分词器会比较特殊,会做一部分的形式转换,有些时候会盲目地切分单词,比如er和e这些常见后缀,会被切掉,所以little变成了littl。】
可能有人不是很懂分词器的作用,这里再次重谈一下:
如果使用的分词器是standard,那你输入的loves会认为是loves,loved会认为是loved;
而english会把loves认为是love,loved认为是love.
所以在english分词器中,loves和loved的搜索用的是love的索引词搜索,而standard中用的是loves和loved的索引词,从搜索效率来说,english的搜索才是我们想要的,它比较灵活。
而且有些分词器会帮你把词组合起来,比如“中国人”这个词不该被拆分成“中”“国”“人”】
修改分词器
修改分词器就是修改mapping中的analyzer,mapping中某个字段一但创建就不能针对这个字段修改,所以只能删除再修改或新增。
PUT /test0106
{
"settings": {
"number_of_shards": 1,
"number_of_replicas": 1
},
"mappings": {
"test":{
"properties": {
"content":{
"type": "text",
"analyzer": "standard"
},
"detail":{
"type": "text",
"analyzer": "english"
}
}
}
}
}
中文分词器
在前面,我们都是使用英文作为字段的数据,因为ElasticSearch默认情况下无法很好地对中文进行分词,它默认只能一个个字地分词,所以它会把“中国人”这个词拆分成“中”“国”“人”。
所以我们需要使用“插件”来对ElasticSearch来进行扩展。
我们常用的中文分词器就是IK分词器。
如何安装
1.去github上下载IK的zip文件,下载的插件版本要与当前使用的elasticsearch版本一致,比如你是elasticsearch6.2.3,就下载6.2.3的【对于没有自己版本的,这时候可能需要下载新的elasticsearch,有些人说可以通过修改pom.xml来强行适配,但还是存在一些问题的。】。github-IK
2.把zip文件中的elasticsearch
文件夹解压到elasticsearch安装目录\plugins
中,并且重命名文件夹为ik-analyzer
3.然后重启elasticsearch
使用
IK分词器提供了两种分词器ik_max_word和ik_smart
- ik_max_word: 会将文本做最细粒度的拆分,比如
北京天安门广场
会被拆分为北京
,京
,天安门广场
,天安门
,天安
,门
,广场
,会尝试各种在IK中可能的组合;
- ik_smart: 会做最粗粒度的拆分,比如会将
北京天安门广场
拆分为北京
,天安门广场
。
- 一般都会使用ik_max_word,只有在某些确实只需要最粗粒度的时候才使用ik_smart。
// 测试一:比较标准分词器和IK分词器的区别:
// 结果:标准分词器只会一个个字地拆分
GET /_analyze
{
"analyzer": "standard",
"text": "北京天安门广场"
}
GET /_analyze
{
"analyzer": "ik_max_word",
"text": "北京天安门广场"
}
GET /_analyze
{
"analyzer": "ik_smart",
"text": "北京天安门广场"
}
// 测试二:给某个字段的mapping配置分词器为ik_max_word,插入测试数据,并进行搜索
PUT /test0107
{
"mappings": {
"test": {
"properties": {
"content": {
"type": "text",
"analyzer": "ik_max_word"
}
}
}
}
}
PUT /test0107/test/1
{
"content":"北京天安门广场"
}
PUT /test0107/test/2
{
"content":"上海世博会"
}
PUT /test0107/test/3
{
"content":"北京鸟巢"
}
PUT /test0107/test/4
{
"content":"上海外滩"
}
// 开始搜索:
GET /test0107/test/_search
{
"query": {
"match": {
"content": "北京"
}
}
}
GET /test0107/test/_search
{
"query": {
"match": {
"content": "鸟巢"
}
}
}
GET /test0107/test/_search
{
"query": {
"match": {
"content": "世博会"
}
}
}
// 这条搜索是搜索不出结果的,因为分词的结果没有“京”字
GET /test0107/test/_search
{
"query": {
"match": {
"content"