Elasticsearch Java Rest Client API 整理总结 (二) —— SearchAPI
引言
在上一篇 中主要介绍了 Document API,本节中讲解 search API
Search APIs
Java High Level REST Client 支持下面的 Search API:
Search API
Search Request
searchRequest 用来完成和搜索文档,聚合,建议等相关的任何操作同时也提供了各种方式来完成对查询结果的高亮操作。
最基本的查询操作如下
SearchRequest searchRequest = new SearchRequest();
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.matchAllQuery()); // 添加 match_all 查询
searchRequest.source(searchSourceBuilder); // 将 SearchSourceBuilder 添加到 SeachRequest 中
可选参数
SearchRequest searchRequest = new SearchRequest("posts"); // 设置搜索的 index
searchRequest.types("doc"); // 设置搜索的 type
除了配置 index 和 type 外,还有一些其他的可选参数
searchRequest.routing("routing"); // 设置 routing 参数
searchRequest.preference("_local"); // 配置搜索时偏爱使用本地分片,默认是使用随机分片
什么是 routing 参数?
当索引一个文档的时候,文档会被存储在一个主分片上。在存储时一般都会有多个主分片。Elasticsearch 如何知道一个文档应该放置在哪个分片呢?这个过程是根据下面的这个公式来决定的:
shard = hash(routing) % number_of_primary_shards
routing是一个可变值,默认是文档的_id,也可以设置成一个自定义的值number_of_primary_shards是主分片数量
所有的文档 API 都接受一个叫做 routing 的路由参数,通过这个参数我们可以自定义文档到分片的映射。一个自定义的路由参数可以用来确保所有相关的文档——例如所有属于同一个用户的文档——都被存储到同一个分片中。
使用 SearchSourceBuilder
对搜索行为的配置可以使用 SearchSourceBuilder 来完成,来看一个实例
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); // 默认配置
sourceBuilder.query(QueryBuilders.termQuery("user", "kimchy")); // 设置搜索,可以是任何类型的 QueryBuilder
sourceBuilder.from(0); // 起始 index
sourceBuilder.size(5); // 大小 size
sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS)); // 设置搜索的超时时间
设置完成后,就可以添加到 SearchRequest 中。
SearchRequest searchRequest = new SearchRequest();
searchRequest.source(sourceBuilder);
构建查询条件
查询请求是通过使用 QueryBuilder 对象来完成的,并且支持 Query DSL。
DSL (domain-specific language) 领域特定语言,是指专注于某个应用程序领域的计算机语言。
— 百度百科
可以使用构造函数来创建 QueryBuilder
MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder("user", "kimchy");
QueryBuilder 创建后,就可以调用方法来配置它的查询选项:
matchQueryBuilder.fuzziness(Fuzziness.AUTO); // 模糊查询
matchQueryBuilder.prefixLength(3); // 前缀查询的长度
matchQueryBuilder.maxExpansions(10); // max expansion 选项,用来控制模糊查询
也可以使用QueryBuilders 工具类来创建 QueryBuilder 对象。这个类提供了函数式编程风格的各种方法用来快速创建 QueryBuilder 对象。
QueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("user", "kimchy")
.fuzziness(Fuzziness.AUTO)
.prefixLength(3)
.maxExpansions(10);
fuzzy-matching 拼写错误时的匹配:
好的全文检索不应该是完全相同的限定逻辑,相反,可以扩大范围来包括可能的匹配,从而根据相关性得分将更好的匹配放在前面。
例如,搜索
quick brown fox时会匹配一个包含fast brown foxes的文档
不论什么方式创建的 QueryBuilder ,最后都需要添加到 ``SearchSourceBuilder` 中
searchSourceBuilder.query(matchQueryBuilder);
构建查询 文档中提供了一个丰富的查询列表,里面包含各种查询对应的QueryBuilder 对象以及QueryBuilder helper 方法,大家可以去参考。
关于构建查询的内容会在下篇文章中讲解,敬请期待。
指定排序
SearchSourceBuilder 允许添加一个或多个SortBuilder 实例。这里包含 4 种特殊的实现, (Field-, Score-, GeoDistance- 和 ScriptSortBuilder)
sourceBuilder.sort(new ScoreSortBuilder().order(SortOrder.DESC)); // 根据分数 _score 降序排列 (默认行为)
sourceBuilder.sort(new FieldSortBuilder("_uid").order(SortOrder.ASC)); // 根据 id 降序排列
过滤数据源
默认情况下,查询请求会返回文档的内容 _source ,当然我们也可以配置它。例如,禁止对 _source 的获取
sourceBuilder.fetchSource(false);
也可以使用通配符模式以更细的粒度包含或排除特定的字段:
String[] includeFields = new String[] {"title", "user", "innerObject.*"};
String[] excludeFields = new String[] {"_type"};
sourceBuilder.fetchSource(includeFields, excludeFields);
高亮请求
可以通过在 SearchSourceBuilder 上设置 HighlightBuilder 完成对结果的高亮,而且可以配置不同的字段具有不同的高亮行为。
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
HighlightBuilder highlightBuilder = new HighlightBuilder();
HighlightBuilder.Field highlightTitle =
new HighlightBuilder.Field("title"); // title 字段高亮
highlightTitle.highlighterType("unified"); // 配置高亮类型
highlightBuilder.field(highlightTitle); // 添加到 builder
HighlightBuilder.Field highlightUser = new HighlightBuilder.Field("user");
highlightBuilder.field(highlightUser);
searchSourceBuilder.highlighter(highlightBuilder);
聚合请求
要实现聚合请求分两步
- 创建合适的 ``AggregationBuilder`
- 作为参数配置在 ``SearchSourceBuilder` 上
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
TermsAggregationBuilder aggregation = AggregationBuilders.terms("by_company")
.field("company.keyword");
aggregation.subAggregation(AggregationBuilders.avg("average_age")
.field("age"));
searchSourceBuilder.aggregation(aggregation);
建议请求 Requesting Suggestions
SuggestionBuilder 实现类是由 SuggestBuilders 工厂类来创建的。
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
SuggestionBuilder termSuggestionBuilder =
SuggestBuilders.termSuggestion("user").text("kmichy");
SuggestBuilder suggestBuilder = new SuggestBuilder();
suggestBuilder.addSuggestion("suggest_user", termSuggestionBuilder);
searchSourceBuilder.suggest(suggestBuilder);
对请求和聚合分析
分析 API 可用来对一个特定的查询操作中的请求和聚合进行分析,此时要将SearchSourceBuilder 的 profile标志位设置为 true
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.profile(true);
只要 SearchRequest 执行完成,对应的 SearchResponse 响应中就会包含 分析结果
同步执行
同步执行是阻塞式的,只有结果返回后才能继续执行。
SearchResponse searchResponse = client.search(searchRequest);
异步执行
异步执行使用的是 listener 对结果进行处理。
ActionListener<SearchResponse> listener = new ActionListener<SearchResponse>() {
@Override
public void onResponse(SearchResponse searchResponse) {
// 查询成功
}
@Override
public void onFailure(Exception e) {
// 查询失败
}
};
查询响应 SearchResponse
查询执行完成后,会返回 SearchResponse 对象,并在对象中包含查询执行的细节和符合条件的文档集合。
归纳一下, SerchResponse 包含的信息如下
- 请求本身的信息,如 HTTP 状态码,执行时间,或者请求是否超时
RestStatus status = searchResponse.status(); // HTTP 状态码
TimeValue took = searchResponse.getTook(); // 查询占用的时间
Boolean terminatedEarly = searchResponse.isTerminatedEarly(); // 是否由于 SearchSourceBuilder 中设置 terminateAfter 而过早终止
boolean timedOut = searchResponse.isTimedOut(); // 是否超时
- 查询影响的分片数量的统计信息,成功和失败的分片
int totalShards = searchResponse.getTotalShards();
int successfulShards = searchResponse.getSuccessfulShards();
int failedShards = searchResponse.getFailedShards();
for (ShardSearchFailure failure : searchResponse.getShardFailures()) {
// failures should be handled here
}
检索 SearchHits
要访问返回的文档,首先要在响应中获取其中的 SearchHits
SearchHits hits = searchResponse.getHits();
SearchHits 中包含了所有命中的全局信息,如查询命中的数量或者最大分值:
long totalHits = hits.getTotalHits();
float maxScore = hits.getMaxScore();
查询的结果嵌套在 SearchHits 中,可以通过遍历循环获取
SearchHit[] searchHits = hits.getHits();
for (SearchHit hit : searchHits) {
// do something with the SearchHit
}
SearchHit 提供了如 index , type, docId 和每个命中查询的分数
String index = hit.getIndex();
String type = hit.getType();
String id = hit.getId();
float score = hit.getScore();
而且,还可以获取到文档的源数据,以 JSON-String 形式或者 key-value map 对的形式。在 map 中,字段可以是普通类型,或者是列表类型,嵌套对象。
String sourceAsString = hit.getSourceAsString();
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
String documentTitle = (String) sourceAsMap.get("title");
List<Object> users = (List<Object>) sourceAsMap.get("user");
Map<String, Object> innerObject =
(Map<String, Object>) sourceAsMap.get("innerObject");
Search API 查询关系
上面的 QueryBuilder , SearchSourceBuilder 和 SearchRequest 之间都是嵌套关系,为此我专门整理了一个关系图,以便更清楚的确认它们之间的关系。感兴趣的同学可用此图与前面的 API 进行对应,以加深理解。

结语
本篇包含了 Java High level Rest Client 的 SearchAPI 部分,获取高亮,聚合,分析的结果并没有在本文涉及,需要的同学可参考官方文档,下篇会包含查询构建,敬请期待~
系列文章列表
- Elasticsearch Java Rest Client API 整理总结 (一)——Document API
- Elasticsearch Java Rest Client API 整理总结 (二) —— SearchAPI
- Elasticsearch Java Rest Client API 整理总结 (三)——Building Queries
Elasticsearch Java Rest Client API 整理总结 (二) —— SearchAPI的更多相关文章
- Elasticsearch Java Rest Client API 整理总结 (三)——Building Queries
目录 上篇回顾 Building Queries 匹配所有的查询 全文查询 Full Text Queries 什么是全文查询? Match 全文查询 API 列表 基于词项的查询 Term Term ...
- Elasticsearch Java Rest Client API 整理总结 (一)——Document API
目录 引言 概述 High REST Client 起步 兼容性 Java Doc 地址 Maven 配置 依赖 初始化 文档 API Index API GET API Exists API Del ...
- Elasticsearch Java Rest Client API 整理总结 (一)
http://www.likecs.com/default/index/show?id=39549
- java微信开发API解析(二)-获取消息和回复消息
java微信开发API解析(二)-获取消息和回复消息 说明 * 本演示样例依据微信开发文档:http://mp.weixin.qq.com/wiki/home/index.html最新版(4/3/20 ...
- Elasticsearch Java Rest Client简述
ESJavaClient的历史 JavaAPI Client 优势:基于transport进行数据访问,能够使用ES集群内部的性能特性,性能相对好 劣势:client版本需要和es集群版本一致,数据序 ...
- HTML5 <Audio/>标签Api整理(二)
1.实例2: 相对较完整 Html代码: <style> #volumeSlider .slider-selection { background:#bababa; } </styl ...
- HBase Client API使用(二)---查询及过滤器
相关知识 创建表插入数据删除等见:http://www.cnblogs.com/wishyouhappy/p/3735077.html HBase API简介见:http://www.cnblogs. ...
- Java REST Client API
https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.3/java-rest-high-supported-apis.htm ...
- Java基础知识➣Stream整理(二)
概述 在Java数据流用到的流包括(Stream).文件(File流)和I/O流 ,利用该三个流操作数据的传输. Java控制台输入输出流 读取控制台使用数据流: BufferedReader和Inp ...
随机推荐
- Jboss7或者wildfly部署war包的问题
如果在Jboss7或者wildfly中部署war包是遇到类似如下错误: "{"JBAS014671: Failed services" => {"jbos ...
- 灰度发布:灰度很简单,发布很复杂&灰度发布(灰度法则)的6点认识
什么是灰度发布,其要点有哪些? 最近跟几个聊的来的同行来了一次说聚就聚的晚餐,聊了一下最近的工作情况如何以及未来规划等等,酒足饭饱后我们聊了一个话题“灰度发布”. 因为笔者所负责的产品还没有达到他们产 ...
- IBM ServerGuide引导盘全系列下载网址
IBM ServerGuide引导盘全系列下载网址 官网链接 https://www.ibm.com/support/home/docdisplay?lndocid=SERV-GUIDE v9.30 ...
- Linux 快速查看系统配置-熟悉新环境的配置
问题背景: 当我们使用新的环境的时候,需要很快得熟悉自己环境的配置,这时候我们如果知道一些命令就极为方便了.这样你就能对自己的环境较为熟悉,进行工作的时候也能随心所欲了. 如果你使用workstati ...
- OpenGL_Qt学习笔记之_03(平面图形的着色和旋转)(转)
http://www.cnblogs.com/tornadomeet/archive/2012/08/23/2653305.html 在这一节中主要简单介绍下怎样给平面几何着色,以及怎样让绘制出来的几 ...
- MongoDB基础之 安装
本篇来介绍MongoDB的安装.安装版本是3.4.18 如果安装老版本的mongodb,你会发现安装比较顺利,但是新版本的mongo安装稍微麻烦一点 ,主要是多了安全机制认证等步骤. 1.下载mong ...
- Python接口自动化--URL参数的编码和解码 6
# _*_ coding:utf-8 _*_ #python2 import urllib #有时,需要从上一个请求的url获取参数,传到下一个请求中,中文会显示为编码的形式,这时候就需要进行解码 u ...
- NOI 2018网络同步赛(游记?)
刚中考完那段时间比较无聊,报名了一个同步赛,报完名才发现成绩单是要挂到网上的,而且因为报的早给了一个很靠前的考号...那布星啊,赶紧学点东西,于是在一周内学了网络流,Treap以及一些数论. Day1 ...
- [ERROR] Failed to execute goal org.mybatis.generator:mybatis-generator-maven-plugin:1.3.2:generate (default-cli) on project SSMMavenPro: configfile D:\java\PermissionPro\src\main\resources\generatorCo
看看自己的generatorConfig.xml文件是否放错,反正我不小心resources文件放在src目录下,并没有放在main目录下,所有找不带该文件
- Spark项目之电商用户行为分析大数据平台之(十)IDEA项目搭建及工具类介绍
一.创建Maven项目 创建项目,名称为LogAnalysis 二.常用工具类 2.1 配置管理组建 ConfigurationManager.java import java.io.InputStr ...