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. 一只简单的网络爬虫(基于linux C/C++)————线程相关

    爬虫里面采用了多线程的方式处理多个任务,以便支持并发的处理,把主函数那边算一个线程的话,加上一个DNS解析的线程,以及我们可以设置的max_job_num值,最多使用了1+1+max_job_num个 ...

  2. 10_CSS入门和高级技巧(8)

    图片透明 先来复习一下盒子的透明问题: opacity:0.6; 介于0~1之间,为了让IE兼容,我们要使用IE自己的滤镜: filter:alpha(opacity=60); 盒子的透明,会让里面的 ...

  3. 【HBase】带你了解一哈HBase的各种预分区

    目录 简单了解 概述 设置预分区 一.手动指定预分区 二.使用16进制算法生成预分区 三.将分区规则写在文本文件中 四.使用JavaAPI进行预分区 简单了解 概述 由上图可以看出,每一个表都有属于自 ...

  4. css3的 calc属性无效问题解决

    css3的 calc:计算属性. 运算符两边需要加空格,才有效. 错误示例:.mystyle{width:calc(100%-25px)}这样是不生效的 运算符"+ - * /"左 ...

  5. 环境篇:Kylin3.0.1集成CDH6.2.0

    环境篇:Kylin3.0.1集成CDH6.2.0 Kylin是什么? Apache Kylin™是一个开源的.分布式的分析型数据仓库,提供Hadoop/Spark 之上的 SQL 查询接口及多维分析( ...

  6. 使用Optional,不再头疼NPE

    前言 在 Java 语言开发中,可能大多数程序员遇到最多的异常就是 NullPointException 空指针异常了.这个当初语言的开发者"仅仅因为这样实现起来更容易"而允许空引 ...

  7. flink批处理从0到1学习

    一.DataSet API之Data Sources(消费者之数据源) 介绍: flink提供了大量的已经实现好的source方法,你也可以自定义source 通过实现sourceFunction接口 ...

  8. CTR学习笔记&代码实现5-深度ctr模型 DeepCrossing -> DCN

    之前总结了PNN,NFM,AFM这类两两向量乘积的方式,这一节我们换新的思路来看特征交互.DeepCrossing是最早在CTR模型中使用ResNet的前辈,DCN在ResNet上进一步创新,为高阶特 ...

  9. shrine

    0x01 import flask import os app = flask.Flask(__name__) app.config['FLAG'] = os.environ.pop('FLAG') ...

  10. 7、会话框添加查看get与post请求类型

    前言 在使用fiddler抓包的时候,查看请求类型get和post每次只有点开该请求,在Inspectors才能查看get和post请求,不太方便.于是可以在会话框直接添加请求方式. 一.添加会话框菜 ...