ES[7.6.x]学习笔记(十二)高亮 和 搜索建议
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>"
]
}
}
……
我们看到在返回的结果中,增加了highlight
,highlight
里有我们指定的高亮字段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]学习笔记(十二)高亮 和 搜索建议的更多相关文章
- python3.4学习笔记(十二) python正则表达式的使用,使用pyspider匹配输出带.html结尾的URL
python3.4学习笔记(十二) python正则表达式的使用,使用pyspider匹配输出带.html结尾的URL实战例子:使用pyspider匹配输出带.html结尾的URL:@config(a ...
- Go语言学习笔记十二: 范围(Range)
Go语言学习笔记十二: 范围(Range) rang这个关键字主要用来遍历数组,切片,通道或Map.在数组和切片中返回索引值,在Map中返回key. 这个特别像python的方式.不过写法上比较怪异使 ...
- java jvm学习笔记十二(访问控制器的栈校验机制)
欢迎装载请说明出处:http://blog.csdn.net/yfqnihao 本节源码:http://download.csdn.net/detail/yfqnihao/4863854 这一节,我们 ...
- (C/C++学习笔记) 十二. 指针
十二. 指针 ● 基本概念 位系统下为4字节(8位十六进制数),在64位系统下为8字节(16位十六进制数) 进制表示的, 内存地址不占用内存空间 指针本身是一种数据类型, 它可以指向int, char ...
- Python学习笔记(十二)—Python3中pip包管理工具的安装【转】
本文转载自:https://blog.csdn.net/sinat_14849739/article/details/79101529 版权声明:本文为博主原创文章,未经博主允许不得转载. https ...
- ROS学习笔记十二:使用gazebo在ROS中仿真
想要在ROS系统中对我们的机器人进行仿真,需要使用gazebo. gazebo是一种适用于复杂室内多机器人和室外环境的仿真环境.它能够在三维环境中对多个机器人.传感器及物体进行仿真,产生实际传感器反馈 ...
- JavaScript权威设计--命名空间,函数,闭包(简要学习笔记十二)
1.作为命名空间的函数 有时候我们需要声明很多变量.这样的变量会污染全局变量并且可能与别人声明的变量产生冲突. 这时.解决办法是将代码放入一个函数中,然后调用这个函数.这样全局变量就变成了 局部变量. ...
- MySQL学习笔记十二:数据备份与恢复
数据备份 1.物理备份与逻辑备份 物理备份 物理备份就是将数据库的数据文件,配置文件,日志文件等复制一份到其他路径上,这种备份速度一般较快,因为只有I/O操作.进行物理备份时,一般都需要关闭mysql ...
- python 学习笔记十二 CSS基础(进阶篇)
1.CSS 简介 CSS 指层叠样式表 (Cascading Style Sheets) 样式定义如何显示 HTML 元素 样式通常存储在样式表中 把样式添加到 HTML 4.0 中,是为了解决内容与 ...
- Java基础学习笔记十二 类、抽象类、接口作为方法参数和返回值以及常用API
不同修饰符使用细节 常用来修饰类.方法.变量的修饰符 public 权限修饰符,公共访问, 类,方法,成员变量 protected 权限修饰符,受保护访问, 方法,成员变量 默认什么也不写 也是一种权 ...
随机推荐
- USACO Training Section 1.1 Your Ride Is Here
题目描述 众所周知,在每一个彗星后都有一只UFO.这些UFO时常来收集地球上的忠诚支持者.不幸的是,他们的飞碟每次出行都只能带上一组支持者.因此,他们要用一种聪明的方案让这些小组提前知道谁会被彗星带走 ...
- tarjan 算法应用
主要讲证明,流程倒是也有 然后发现自己并不会严谨证明 其实后面一些部分流程还是挺详细 本来这篇blog叫做"图论部分算法证明",然后发现OI中的图论想完全用数学上的方法证明完全超出 ...
- P4370 [Code+#4]组合数问题2
题目要求当\(0\leq a\leq b\leq n\)时,\(k\)个\(\tbinom{b}{a}\)的和的最大值 观察杨辉三角形,可以发现,最大的\(\tbinom{b}{a}\),为\(\tb ...
- 题解 CF545A 【Toy Cars】
题目传送门 太弱了,只能写写A题的题解 题意 给你一个 $n·n$ 的矩阵,翻车分三种情况: 如果 $a_i,_j=1$ ,记录第 $i$ 辆车 如果 $a_i,_j=2$ ,记录第 $j$ 辆车 如 ...
- 10 微信小程序路由跳转
一.四种跳转方式 API路由详解 除了tabBar这种底部跳转的方法,我们还有路由跳转,以下四种方式: 1. wx.switchTab() :跳转到 tabBar 页面,并关闭其他所有非 tabBar ...
- 【UEFI】---史上最全的X86平台启动流程分析(软硬结合)
最近研究了下X86处理器的启动流程分析,相比于常见的ARM来说,X86平台启动流程真的复杂了很多,本次基于项目实际的两个问题入手,研究了包括以下几个部分的内容: 1. 从硬件角度看启动流程 2. 从软 ...
- OSG程序设计之Hello World 2.0
现在为Hello World添加一些键盘响应事件. //需要多添加两个库:osgGAd.lib.osgd.lib 代码如下: #include <osgDB/ReadFile> #incl ...
- 创造DotNet Core轻量级框架【一】
前言 net core 已经出了很久了,网上的各种框架也很多了,但是没看到一个很小很轻的框架,基本都是那种啥功能都有,但是我需要的功能只占他们框架的百分之几,很少很少,所以自己创造一个框架. 因为之前 ...
- JUC之CAS
CAS(全称为CompareAndSwap,也有说是CompareAndSet,都差不多)是一条CPU并发原语,它的功能是判断内存某个位置的值是否为预期值,如果是则更改为新的值,判断预期值和更改新值的 ...
- [csu1508 地图的四着色]二分图染色
抽象后的题意:给一个不超过30个点的图,A从中选不超过5个点涂红绿两种颜色,B用黑白两种颜色把剩下的涂完,任意一条边两端的颜色不同,求每种颜色至少用涂一次的方案数 思路:枚举A涂的点的集合,将原图分成 ...