ES当中大部分的内容都已经学习完了,今天呢算是对前面内容的查漏补缺,把ES中非常实用的功能整理一下,在以后的项目开发中,这些功能肯定是对你的项目加分的,我们来看看吧。

高亮

高亮在搜索功能中是十分重要的,我们希望搜索的内容在搜索结果中重点突出,让用户聚焦在搜索的内容上。我们看看在ES当中是怎么实现高亮的,我们还用之前的索引ik_index,前面的章节,我们搜索过香蕉好吃,但是返回的结果中并没有高亮,那么想要在搜索结果中,对香蕉好吃高亮该怎么办呢?我们看看,

POST /ik_index/_search
{
"query": {
"bool": {
"must": {
"match": {
"desc": "香蕉好吃"
}
}
}
},
"highlight": {
"fields": {
"desc": {}
}
}
}

我们重点看一下请求体中的highlight部分,这部分就是对返回结果高亮的设置,fields字段中,指定哪些字段需要高亮,我们指定了desc字段,执行一下,看看结果吧。

{
"took": 73,
"timed_out": false,
"_shards": { "total": 1,"successful": 1,"skipped": 0,"failed": 0},
"hits": {
"total": {
"value": 5,
"relation": "eq"
},
"max_score": 1.3948275,
"hits": [
{
"_index": "ik_index",
"_type": "_doc",
"_id": "2",
"_score": 1.3948275,
"_source": {
"id": 1,
"title": "香蕉",
"desc": "香蕉真好吃"
},
"highlight": {
"desc": [
"<em>香蕉</em>真<em>好吃</em>"
]
}
}
……

我们看到在返回的结果中,增加了highlighthighlight里有我们指定的高亮字段desc,它的值是<em>香蕉</em>真<em>好吃</em>,其中“香蕉”和“好吃”字段在<em>标签中,前端的小伙伴就可以针对这个<em>标签写样式了。我们再看看程序当中怎么设置高亮,继续使用上一节中的搜索的程序,

    public void searchIndex() throws IOException {
SearchRequest searchRequest = new SearchRequest("ik_index");
SearchSourceBuilder ssb = new SearchSourceBuilder();
QueryBuilder qb = new MatchQueryBuilder("desc","香蕉好吃");
ssb.query(qb); HighlightBuilder highlightBuilder = new HighlightBuilder();
highlightBuilder.field("desc"); ssb.highlighter(highlightBuilder); searchRequest.source(ssb);
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT); SearchHit[] hits = response.getHits().getHits();
for (SearchHit hit : hits) {
String record = hit.getSourceAsString();
HighlightField highlightField = hit.getHighlightFields().get("desc"); for (Text fragment : highlightField.getFragments()) {
System.out.println(fragment.string());
}
}
}

我们重点关注一下HighlightBuilder,我们在发送请求前,创建HighlightBuilder,并指定高亮字段为desc。搜索结束后,我们取结果,从hit当中取出高亮字段desc,然后打印出fragment,运行一下,看看结果吧,

<em>香蕉</em>真<em>好吃</em>
<em>香蕉</em>真<em>好吃</em>
橘子真<em>好吃</em>
桃子真<em>好吃</em>
苹果真<em>好吃</em>

完全符合预期,“香蕉好吃”被分词后,在搜索结果中都增加了<em>标签,我们可不可以自定义高亮标签呢?当然是可以的,我们稍微改一下程序就可以了,

HighlightBuilder highlightBuilder = new HighlightBuilder();
highlightBuilder.field("desc"); highlightBuilder.preTags("<b>");
highlightBuilder.postTags("</b>"); ssb.highlighter(highlightBuilder);

HighlightBuilder中,使用preTags添加起始标签,指定为<b>,用postTags添加闭合标签,指定为</b>,再运行一下,看看结果,

<b>香蕉</b>真<b>好吃</b>
<b>香蕉</b>真<b>好吃</b>
橘子真<b>好吃</b>
桃子真<b>好吃</b>
苹果真<b>好吃</b>

结果完全正确,用<b>替换了<em>,是不是很灵活。接下来我们再看看搜索建议。

搜索建议

“搜索建议”这个功能也是相当实用的,当我们在搜索框中输入某个字时,与这个字的相关搜索内容就会罗列在下面,我们选择其中一个搜索就可以了,省去了敲其他字的时间。我们看看ES中是怎么实现“搜索建议”的。

如果要在ES中使用“搜索建议”功能,是需要特殊设置的,要设置一个类型为completion的字段,由于之前的索引中已经有了数据,再添加字段是会报错的,索引我们新建一个索引,

PUT /my_suggester
{
"settings":{
"analysis":{
"analyzer":{
"default":{
"type":"ik_max_word"
}
}
}
},
"mappings":{
"dynamic_date_formats": [
"MM/dd/yyyy",
"yyyy/MM/dd HH:mm:ss",
"yyyy-MM-dd",
"yyyy-MM-dd HH:mm:ss"
],
"properties":{
"suggest":{
"type":"completion"
}
}
}
}

这已经成了我们新建索引的一个标配了,指定分词器为ik中文分词,动态字段的时间映射格式,以及搜索建议字段,注意suggest字段的类型为completion。我们再添加字段的时候,就要为suggest字段添加值了,如下:

POST /my_suggester/_doc
{
"title":"天气",
"desc":"今天天气不错",
"suggest": {
"input": "天气"
}
} POST /my_suggester/_doc
{
"title":"天空",
"desc":"蓝蓝的天空,白白的云",
"suggest": {
"input": "天空"
}
}

我们向索引中添加了两条数据,大家需要额外注意的是suggest字段的赋值方法,要使用input,我们看一下数据,

suggest字段并没有像其他字段那样展示出来,说明它和其他字段是不一样的。现在我们如果只输入一个“天”字,看看搜索建议能不能给出提示,如下:

POST /my_suggester/_search
{
"suggest": {
"s-test": {
"prefix": "天",
"completion": {
"field": "suggest"
}
}
}
}

在请求体中,suggest就是“搜索建议”的标识,s-test是自定义的一个名称,prefix是前缀,也就是我们输入的“天”字,completion指定搜索建议的字段,我们看看查询的结果,

……
"suggest": {
"s-test": [
{
"text": "天",
"offset": 0,
"length": 1,
"options": [{
"text": "天气",
"_index": "my_suggester",
"_type": "_doc",
"_id": "QtgAWnIBOZNtuLQtJgpt",
"_score": 1,
"_source": { "title": "天气","desc": "今天天气不错","suggest": { "input": "天气"}}
}
,
{
"text": "天空",
"_index": "my_suggester",
"_type": "_doc",
"_id": "T9gAWnIBOZNtuLQtWQoX",
"_score": 1,
"_source": { "title": "天空","desc": "蓝蓝的天空,白白的云","suggest": { "input": "天空"}}
}
]
}
]
}

s-test.options里,包含了两条记录,text字段就是我们写的建议字段,后面_source里还包含对应的数据,下面我们再看看程序里怎么使用“搜索建议”,

public void searchSuggest(String prefix) throws IOException {
SearchRequest searchRequest = new SearchRequest("my_suggester");
SearchSourceBuilder ssb = new SearchSourceBuilder(); CompletionSuggestionBuilder suggest = SuggestBuilders
.completionSuggestion("suggest")
.prefix(prefix); SuggestBuilder suggestBuilder = new SuggestBuilder();
suggestBuilder.addSuggestion("s-test",suggest); ssb.suggest(suggestBuilder); searchRequest.source(ssb);
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT); CompletionSuggestion suggestion = response.getSuggest().getSuggestion("s-test");
for (CompletionSuggestion.Entry.Option option : suggestion.getOptions()) {
System.out.println(option.getText().string());
} } @Test
public void searchSuggest() throws IOException {
eService.searchSuggest("天");
}

我们创建了CompletionSuggestionBuilder,通过方法completionSuggestion指定“搜索建议”字段suggest,并且指定前缀为方法传入的prefix,我们在测试的时候传入"天"字。然后,我们自定义“搜索建议”的名字为s-test,传入前面构造好的suggest

发送请求后,在响应中获取前面自定义的s-test,然后循环options,取出text字段,这就是搜索建议的字段,我们运行一下,看看结果,

天气
天空

完全符合预期,这样用户在搜索的时候,就会给出提示信息了。

好了,今天这两个ES的知识点就全部OK了~ 大家有问题在评论区留言。

ES[7.6.x]学习笔记(十二)高亮 和 搜索建议的更多相关文章

  1. python3.4学习笔记(十二) python正则表达式的使用,使用pyspider匹配输出带.html结尾的URL

    python3.4学习笔记(十二) python正则表达式的使用,使用pyspider匹配输出带.html结尾的URL实战例子:使用pyspider匹配输出带.html结尾的URL:@config(a ...

  2. Go语言学习笔记十二: 范围(Range)

    Go语言学习笔记十二: 范围(Range) rang这个关键字主要用来遍历数组,切片,通道或Map.在数组和切片中返回索引值,在Map中返回key. 这个特别像python的方式.不过写法上比较怪异使 ...

  3. java jvm学习笔记十二(访问控制器的栈校验机制)

    欢迎装载请说明出处:http://blog.csdn.net/yfqnihao 本节源码:http://download.csdn.net/detail/yfqnihao/4863854 这一节,我们 ...

  4. (C/C++学习笔记) 十二. 指针

    十二. 指针 ● 基本概念 位系统下为4字节(8位十六进制数),在64位系统下为8字节(16位十六进制数) 进制表示的, 内存地址不占用内存空间 指针本身是一种数据类型, 它可以指向int, char ...

  5. Python学习笔记(十二)—Python3中pip包管理工具的安装【转】

    本文转载自:https://blog.csdn.net/sinat_14849739/article/details/79101529 版权声明:本文为博主原创文章,未经博主允许不得转载. https ...

  6. ROS学习笔记十二:使用gazebo在ROS中仿真

    想要在ROS系统中对我们的机器人进行仿真,需要使用gazebo. gazebo是一种适用于复杂室内多机器人和室外环境的仿真环境.它能够在三维环境中对多个机器人.传感器及物体进行仿真,产生实际传感器反馈 ...

  7. JavaScript权威设计--命名空间,函数,闭包(简要学习笔记十二)

    1.作为命名空间的函数 有时候我们需要声明很多变量.这样的变量会污染全局变量并且可能与别人声明的变量产生冲突. 这时.解决办法是将代码放入一个函数中,然后调用这个函数.这样全局变量就变成了 局部变量. ...

  8. MySQL学习笔记十二:数据备份与恢复

    数据备份 1.物理备份与逻辑备份 物理备份 物理备份就是将数据库的数据文件,配置文件,日志文件等复制一份到其他路径上,这种备份速度一般较快,因为只有I/O操作.进行物理备份时,一般都需要关闭mysql ...

  9. python 学习笔记十二 CSS基础(进阶篇)

    1.CSS 简介 CSS 指层叠样式表 (Cascading Style Sheets) 样式定义如何显示 HTML 元素 样式通常存储在样式表中 把样式添加到 HTML 4.0 中,是为了解决内容与 ...

  10. Java基础学习笔记十二 类、抽象类、接口作为方法参数和返回值以及常用API

    不同修饰符使用细节 常用来修饰类.方法.变量的修饰符 public 权限修饰符,公共访问, 类,方法,成员变量 protected 权限修饰符,受保护访问, 方法,成员变量 默认什么也不写 也是一种权 ...

随机推荐

  1. vue无法自动打开浏览器

    原文链接: 点我 如果不能自动打开浏览器,是因为没有安装插件. 插件安装的方法1.安装插件,在cmd中输入: $ npm i open-browser-webpack-plugin --save这里的 ...

  2. 数据结构--顺序栈--C++实现

    #include <iostream> #define MaxSize 5000 using namespace std; template <typename T> clas ...

  3. CodeForces-259B]Little Elephant and Magic Square

      Little Elephant loves magic squares very much. A magic square is a 3 × 3 table, each cell contains ...

  4. RobotFrameWork 自动化环境搭建(基于 python3.6)

    一.需要安装的工具目录 安装 python3.6.0 我这里采用的是 python3.6 (目前慢慢市场在推广 python3.0 版本了) 安装 wxPython(Python 非常有名的一个GUI ...

  5. Python爬虫(二)爬百度贴吧楼主发言

    爬取电影吧一个帖子里的所有楼主发言: # python2 # -*- coding: utf-8 -*- import urllib2 import string import re class Ba ...

  6. mybatis的关系映射

    一.多对一的映射关系 举例:根据员工编号查询员工所在部门的部门信息 第一步,需要在多的一方也就是员工实体类中持有一的一方部门实体类的引用 第二步,在dao接口中声明方法 第三步,在mapper中实现该 ...

  7. Struts Scan工具的使用

    前言 最近看了关于Struts2漏洞,参考文章 https://www.freebuf.com/vuls/168609.html,这篇文章里对Struts2的漏洞及原理进行了详细的讲解.自己也从网上找 ...

  8. Django 设置admin后台表和App(应用)为中文名

    设置表名为中文 1.设置Models.py文件 class Post(models.Model): name = models.CharField() --省略其他字段信息 class Meta: v ...

  9. 【Hadoop离线基础总结】Mac版VMware Fusion虚拟机磁盘挂载

    步骤概览 1.打开所要挂载磁盘的虚拟机的设置(此时必须关机) 2.打开硬盘设置 3.添加设备 4.选择新硬盘 5.设置如下图 6.将虚拟机开机,输入 df-lh ,查看当前虚拟机磁盘 7.输入 fdi ...

  10. 常用中文分词工具分词&词性标注简单应用(jieba、pyhanlp、pkuseg、foolnltk、thulac、snownlp、nlpir)

    1.jieba分词&词性标注 import jieba import jieba.posseg as posseg txt1 =''' 文本一: 人民网华盛顿3月28日电(记者郑琪)据美国约翰 ...