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. XML--XML从入门到精通 Part 1 认识XML

    XML 指可扩展标记语言(EXtensible Markup Language) XML 是一种标记语言,很类似 HTML XML 的设计宗旨是传输数据,而非显示数据 XML 标签没有被预定义.您需要 ...

  2. 图论--2-SAT--HDU/HDOJ 1814 Peaceful Commission

    Peaceful Commission Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Oth ...

  3. P3831 [SHOI2012]回家的路

    P3831 [SHOI2012]回家的路 分层图基础题,就是建图稍有麻烦   #include<cstdio> #include<algorithm> #include< ...

  4. python(安装)

    1.下载安装包 https://www.python.org/downloads/ 2.安装 默认安装路径:C:\python3(建议自定义安装路径) 3.配置环境变量 [右键计算机]-->[属 ...

  5. java程序猿面试系列之jvm专题

    前言 因为疫情的影响,现在都变成金五银六了.为了方便大家,在此开一个程序猿面试系列.总结各大公司所问的问题,希望能够帮助到大家,适合初中级java程序猿阅读. 1. Java类实例化时,JVM执行顺序 ...

  6. javascript阻止子元素继承父元素事件

    $('.box').on('click', function (e) { if(e.target == this) { console.log(e.target) } })

  7. linux关于suid提权笔记

    suid全称是Set owner User ID up on execution.这是Linux给可执行文件的一个属性,上述情况下,普通用户之所以也可以使用ping命令,原因就在我们给ping这个可执 ...

  8. J - Super Mario HDU - 4417 线段树 离线处理 区间排序

    J - Super Mario HDU - 4417 这个题目我开始直接暴力,然后就超时了,不知道该怎么做,直接看了题解,这个习惯其实不太好. 不过网上的思路真的很厉害,看完之后有点伤心,感觉自己应该 ...

  9. 简单ajax跨域请求

    最近遇到需要ajax跨域的需求 首先看下不做任何处理特别处理的ajax跨域请求会出现什么样的错误 客户端代码: <script type="text/javascript"& ...

  10. Redis 学习笔记(一) 字符串 SDS

    SDS 简单动态字符串. SDS的结构: struct sdshdr{ int len;//记录BUF数组中已使用字节的数量 ,等于SDS所八寸字符串的长度 int free;//记录BUF数组中未使 ...