文本搜索及分词器相关高级特性是我们每个es爱好者必须要掌握的核心特性,今天我们认真逐条分析一下:
一、文本搜索
文本索引创建过程
索引的创建原理是倒排索引,前面的文章已经多长分析过,这里就不在分析了。
文本的搜索过程
实战中我们常用 match 进行匹配查询,其查询过程如下:
2.1、es将查询的字符传入对应的分析器中,对其进行分词,把分词后的每个词语变换为对应的底层lucene term 查询;
2.2、es用term查询在倒排索引中查找每个term,获取一组包含term 的文档集合;
2.3、es根据文本相关度给每个文档打分计算,然后按照相关性进行倒序排列;
2.4、最后根据得分高低返回匹配文档;
二、分词器简介
分析器使用的时机是:创建或更新文档时,对相应的文本字段进行分词处理;查询文本字段时,对查询语句进行分词;es的分析器有多种,但所有分析器都遵循三段式原则,即字符过滤器、分词器、词语过滤器,字符过滤器可以有0个或多个,分词器必须只有一个,词语过滤器可以有0个或者多个。
字符过滤器
是分析器处理文本的第一步,接受原始字段,处理特殊符号等,即对文本进行粗加工;es内置的有映射关系字符过滤器,HTML擦除过滤器,正则表达式替换过滤器。
分词器
根据空格及标点符号进行切分,es内置的大概有一下四种:
2.1、标准分词器:对英文基于语法分析;对中文,切分成单字;
2.2、字母分词器:使用非字母的字符作为分词标记;
2.3、小写分词器:功能上等于字母分词器,且把所有的结果转化为小写;
2.4、空格分词器:使用空格作为分词标记;
分词过滤器
对分词器的处理结果进行加工和修改,比如转成小写、删除停用词、添加同义词等,es内置的三种如下:
3.1、Lower case过滤器:所有字母转化成小写形式;
3.2、Stop Token :把停用词从分词结果中移除;
3.3、同义词分词过滤器:为分词结果添加同义词;
三、分析器的使用
测试分析API
1.1、处理英文
<code class="language-plaintext hljs">POST _analyze
{
"analyzer": "standard",
"text": "Hello nandao OK good"
}</code>
1.2、处理中文
<code class="language-plaintext hljs">POST _analyze
{
"analyzer": "standard",
"text": "嵩山少林寺"
}</code>
1.3、索引指定分析器
<code class="language-plaintext hljs">POST /nandao_scenic/_analyze
{
"field": "title",
"text": "山西五台山"
}
</code>
1.4、多条件指定分析器
<code class="language-plaintext hljs">GET _analyze
{
"analyzer": "standard",
"filter": ["lowercase"],
"text": "Hello nandao OK good"
}</code>
内置分析器
es目前内置了五种分析器,简介如下:
2.1、standard 分析器:有standard 分词器、Lower Case 分词过滤器、Stop Token 分词过滤器组成;
2.2、simple分析器:按照非字母字符进行拆分,并将所有字符转化成小写;
2.3、language 分析器:语言分词器;
2.4、whitespace分析器:按照空白字符拆分词语;
2.5、pattern分词器:使用正则表达式拆分词语;
索引时使用分析器
创建索引时使用分析器
<code class="language-plaintext hljs">PUT /nandao_scenic
{
"settings": {
"analysis": {
"analyzer": {
"default":{
"type":"simple"
}
}
}
},
"mappings": {
"properties": {
"title":{
"type": "text"
}
}
}
}</code>
指定参数使用;
<code class="language-plaintext hljs">PUT /nandao_scenic
{
"mappings": {
"properties": {
"title":{
"type": "text",
"analyzer": "whitespace"
}
}
}
}
</code>
搜索时使用分析器
<code class="language-plaintext hljs">PUT /nandao_scenic
{
"mappings": {
"properties": {
"title":{
"type": "text",
"analyzer": "whitespace",
"search_analyzer": "whitespace"
}
}
}
}</code>
自定义分析器
<code class="language-plaintext hljs">PUT /nandao_scenic
{
"settings": {
"analysis": {
"analyzer": {
"comma_analyzer":{
"tokenizer":"comma_tokenizer"
}
},
"tokenizer": {
"comma_tokenizer":{
"type":"pattern",
"pattern":","
}
}
}
},
"mappings": {
"properties": {
"title":{
"type": "text",
"analyzer":"whitespace",
"search_analyzer": "whitespace"
},
"sup_env":{
"type": "text",
"analyzer":"comma_tokenizer"
}
}
}
}</code>
四、中文分析器
中文分析器
常用的有两种:基于词典的分词算法;基于统计的机器学习算法;
IK 分析器
安装IK分析器
<code class="language-plaintext hljs">POST _analyze
{
"analyzer": "ik_max_word",
"text": "山西五台山"
}</code>
最小力度
<code class="language-plaintext hljs">
POST _analyze
{
"analyzer": "ik_smark",
"text": "山西五台山"
}</code>
HanLP 分析器
安装下载步骤:
<code class="language-plaintext hljs">POST _analyze
{
"analyzer": "hanlp_standard",
"text": "山西五台山"
}</code>
五、同义词分析
创建索引时使用同义词
<code class="language-plaintext hljs">PUT /nandao_scenic
{
"settings": {
"analysis": {
"filter": {
"ik_synonyms_filter":{
"type":"synonym",
"synonyms":[
"北京,北平",
"天津,天津为",
"假日,假期"
]
}
},
"analyzer": {
"ik_analyzer_synonyms":{
"tokenizer":"ik_max_word",
"filter":[
"lowercase",
"ik_synonyms_filter"
]
}
}
}
},
"mappings": {
"properties": {
"title":{
"type": "text",
"analyzer": "ik_analyzer_synonyms"
}
}
}
}
</code>
查询时使用同义词
思路是类似的,大家可以自由发挥!
六、停用词分析
停用词过滤器
<code class="language-plaintext hljs">PUT /nandao_scenic1212
{
"settings": {
"analysis": {
"filter": {
"my_stop":{
"type":"stop",
"stopwords":[
"你",
"我",
"的"
]
}
},
"analyzer": {
"standard_stop":{
"tokenizer":"standard",
"filter":[
"my_stop"
]
}
}
}
},
"mappings": {
"properties": {
"title":{
"type": "text",
"analyzer": "standard_stop"
}
}
}
}</code>
内置分析器中使用停用词
<code class="language-plaintext hljs">PUT /nandao_scenic129
{
"settings": {
"analysis": {
"analyzer": {
"my_standard":{
"type":"standard",
"stopwords":[
"你",
"我",
"的"
]
}
}
}
} ,
"mappings": {
"properties": {
"title":{
"type": "text",
"analyzer": "my_standard"
}
}
}
}
</code>
IK分析器中使用停用词
IK自带的只有英文停用词,没有中文停用词;需要自定义添加停用词,放在plugins目录下。
HanLP分析器中使用停用词
<code class="language-plaintext hljs">PUT /nandao_scenic99
{
"settings": {
"analysis": {
"tokenizer": {
"my_tokenizer":{
"type":"hanlp_standard",
"enable_stop_dictionary": true
}
},
"analyzer": {
"my_hanlp":{
"tokenizer":"my_tokenizer"
}
}
}
} ,
"mappings": {
"properties": {
"title":{
"type": "text",
"analyzer": "my_hanlp"
}
}
}
}</code>
其也可以添加自定义停用词,去掉特殊符号等。
七、拼音搜索
拼音分析器插件的安装
下载安装地址
拼音分析器插件的使用
<code class="language-plaintext hljs">POST _analyze
{
"analyzer": "pinyin",
"text": "五台山"
}</code>
八、高亮显示搜索
常用高亮显示搜索
<code class="language-plaintext hljs">GET /nandao_scenic/_search
{
"query": {
"match": {
"title": "山西五台山"
}
},
"highlight": {
"fields": {
"title": {
"pre_tags": "<high>",
"post_tags": "<high>"
}
}
}
}</code>
高亮显示搜索策略
<code class="language-plaintext hljs">GET /nandao_scenic/_search
{
"query": {
"match": {
"title": "山西五台山"
}
},
"highlight": {
"fields": {
"title": {
"type":"plain"
}
}
}
}</code>
java客户端进行高亮显示搜索
<code class="language-plaintext hljs">public void hightLightSearch() {
SearchRequest searchRequest = new SearchRequest();//新建搜索请求
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.matchQuery("title", "山西").operator(Operator.AND));//新建match查询,并设置operator值为and
searchRequest.source(searchSourceBuilder);//设置查询
HighlightBuilder highlightBuilder = new HighlightBuilder();//新建高亮搜索
highlightBuilder.preTags("<high>");//设置高亮标签前缀
highlightBuilder.postTags("</high>");//设置高亮标签后缀
highlightBuilder.field("title");//设置高亮字段
searchSourceBuilder.highlighter(highlightBuilder);//设置高亮搜索
try {
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);//执行搜索
SearchHits searchHits = searchResponse.getHits();//获取搜索结果集
for (SearchHit searchHit : searchHits) {//遍历搜索结果集
Text[] texts = searchHit.getHighlightFields().get("title").getFragments();//得到高亮搜索结果
for (Text text : texts) {//遍历高亮搜索
System.out.println(text);//打印每一个高亮结果
}
System.out.println("---------------------------------------");
}
} catch (Exception e) {
e.printStackTrace();
}
}
</code>
九、拼音纠错
使用es进行拼音纠错
创建索引
<code class="language-plaintext hljs">PUT /nandao_ok
{
"mappings": {
"properties": {
"hot_word":{
"type":"text",
"analyzer": "ik_mak_word"
}
}
}
}
</code>
查询
<code class="language-plaintext hljs">GET /nandao_ok/_search
{
"query": {
"match": {
"hot_word":{
"query": "五台山",
"operator": "and",
"fuzziness": 1
}
}
}
}</code>
精准的拼音纠错:
需要自定义分词过滤器,根据上面的例子,可以自由发挥。
到此、文本搜索及分析器相关的使用分享完毕,大家一定要多多练习,定会早日掌握,下篇我们分析搜索排序算法相关的内容,敬请期待!
转载:https://blog.csdn.net/nandao158/article/details/128561213