Java High Level REST Client需要Java 1.8,并依赖于Elasticsearch核心项目,客户端版本与客户端开发的Elasticsearch版本相同,它接受与TransportClient
相同的请求参数,并返回相同的响应对象,如果需要将应用程序从TransportClient
迁移到新的REST客户端,请参阅迁移指南。
High Level Client保证能够与运行在相同主版本和大于或等于的次要版本上的任何Elasticsearch节点通信。当它与Elasticsearch节点通信时,它不需要在同一个次要版本中,因为它是向前兼容的,这意味着它支持与Elasticsearch的更高的版本进行通信,而不是与其开发的版本进行通信。
6.0客户端能够与任何6.x Elasticsearch节点通信,而6.1客户端肯定能够与6.1,6.2和任何更高版本的6.x版本通信,但是,如果6.1客户端支持6.0节点不知道的某些API的新请求主体字段,则在与先前的Elasticsearch节点版本通信时可能存在不兼容问题,例如在6.1和6.0之间。
建议在将Elasticsearch集群升级到新的主要版本时升级High Level Client,因为REST API重要更改可能会导致意外结果,具体取决于请求命中的节点,并且只有较新版本的客户端才支持新添加的API,一旦集群中的所有节点都升级到新的主版本,客户端应该总是在最后更新。
https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.4/java-rest-high-supported-apis.html
高级别Java REST客户端托管在Maven Central上,所需的最低Java版本为1.8
。
High Level REST Client与Elasticsearch具有相同的发布周期,将版本替换为想要的客户端版本。
如果你正在寻找SNAPSHOT版本,可以通过https://snapshots.elastic.co/maven/获取Elastic Maven Snapshot仓库。
以下是如何使用maven作为依赖关系管理器来配置依赖关系,将以下内容添加到pom.xml
文件中
org.elasticsearch.client
elasticsearch-rest-high-level-client
6.4.2
以下是使用gradle作为依赖关系管理器配置依赖关系的方法,将以下内容添加到build.gradle
文件中:
dependencies {
compile 'org.elasticsearch.client:elasticsearch-rest-high-level-client:6.4.2'
}
任何主要版本(如测试版)的最新版本可能都是基于Lucene Snapshot版本构建的,在这种情况下,你将无法解析客户端的Lucene依赖关系。
例如,如果要使用依赖于Lucene 7.0.0-snapshot-00142c9
的6.0.0-beta1
版本,则必须定义以下存储库。
对于Maven:
elastic-lucene-snapshots
Elastic Lucene Snapshots
http://s3.amazonaws.com/download.elasticsearch.org/lucenesnapshots/00142c9
true
false
对于Gradle:
maven {
url 'http://s3.amazonaws.com/download.elasticsearch.org/lucenesnapshots/00142c9'
}
High Level Java REST Client依赖于以下工件及其传递依赖性:
RestHighLevelClient
实例需要按如下方式构建REST低级别客户端构建器:
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(
new HttpHost("localhost", 9200, "http"),
new HttpHost("localhost", 9201, "http")));
高级别客户端将在内部创建用于根据提供的构建器执行请求的低级别客户端,该低级别客户端维护一个连接池并启动一些线程,因此当你完好无损地关闭高级别客户端时,它将关闭内部低级别客户端以释放这些资源,这可以通过close
来完成:
client.close();
在关于Java High Level Client的本文档的其余部分中,RestHighLevelClient
实例将被引用为client
。
RestHighLevelClient
中的所有API都接受RequestOptions
,你可以用来不会改变Elasticsearch执行请求的的方式自定义请求。例如,你可以在此处指定NodeSelector
来控制哪个节点接收请求,有关自定义选项的更多示例,请参阅低级别客户端文档。
IndexRequest
需要以下参数:
IndexRequest request = new IndexRequest(
"posts",
"doc",
"1");
String jsonString = "{" +
"\"user\":\"kimchy\"," +
"\"postDate\":\"2013-01-30\"," +
"\"message\":\"trying out Elasticsearch\"" +
"}";
request.source(jsonString, XContentType.JSON);
posts
— 索引。doc
— 类型。1
— 文档ID。除了上面显示的String
示例之外,还可以以不同的方式提供文档源:
Map jsonMap = new HashMap<>();
jsonMap.put("user", "kimchy");
jsonMap.put("postDate", new Date());
jsonMap.put("message", "trying out Elasticsearch");
IndexRequest indexRequest = new IndexRequest("posts", "doc", "1")
.source(jsonMap);
Map
提供,可自动转换为JSON格式。XContentBuilder builder = XContentFactory.jsonBuilder();
builder.startObject();
{
builder.field("user", "kimchy");
builder.timeField("postDate", new Date());
builder.field("message", "trying out Elasticsearch");
}
builder.endObject();
IndexRequest indexRequest = new IndexRequest("posts", "doc", "1")
.source(builder);
XContentBuilder
对象提供,Elasticsearch内置辅助生成JSON内容。IndexRequest indexRequest = new IndexRequest("posts", "doc", "1")
.source("user", "kimchy",
"postDate", new Date(),
"message", "trying out Elasticsearch");
Object
键值对提供,转换为JSON格式。可以选择提供以下参数:
request.routing("routing");
request.parent("parent");
request.timeout(TimeValue.timeValueSeconds(1));
request.timeout("1s");
TimeValue
的超时。String
的超时。request.setRefreshPolicy(WriteRequest.RefreshPolicy.WAIT_UNTIL);
request.setRefreshPolicy("wait_for");
WriteRequest.RefreshPolicy
实例提供。String
提供。request.version(2);
request.versionType(VersionType.EXTERNAL);
request.opType(DocWriteRequest.OpType.CREATE);
request.opType("create");
DocWriteRequest.OpType
值提供。String
提供的操作类型:可以为create
或update
(默认)。request.setPipeline("pipeline");
以下列方式执行IndexRequest
时,客户端在继续执行代码之前等待返回IndexResponse
:
IndexResponse indexResponse = client.index(request, RequestOptions.DEFAULT);
执行IndexRequest
也可以以异步方式完成,以便客户端可以直接返回,用户需要通过将请求和侦听器传递给异步索引方法来指定响应或潜在故障的处理方式:
client.indexAsync(request, RequestOptions.DEFAULT, listener);
IndexRequest
和执行完成时要使用的ActionListener
。异步方法不会阻塞并立即返回,一旦完成,如果执行成功完成,则使用onResponse
方法回调ActionListener
,如果失败则使用onFailure
方法。
index
的典型侦听器如下所示:
listener = new ActionListener() {
@Override
public void onResponse(IndexResponse indexResponse) {
}
@Override
public void onFailure(Exception e) {
}
};
onResponse
— 执行成功完成时调用。onFailure
— 当整个IndexRequest
失败时调用。返回的IndexResponse
允许检索有关已执行操作的信息,如下所示:
String index = indexResponse.getIndex();
String type = indexResponse.getType();
String id = indexResponse.getId();
long version = indexResponse.getVersion();
if (indexResponse.getResult() == DocWriteResponse.Result.CREATED) {
} else if (indexResponse.getResult() == DocWriteResponse.Result.UPDATED) {
}
ReplicationResponse.ShardInfo shardInfo = indexResponse.getShardInfo();
if (shardInfo.getTotal() != shardInfo.getSuccessful()) {
}
if (shardInfo.getFailed() > 0) {
for (ReplicationResponse.ShardInfo.Failure failure :
shardInfo.getFailures()) {
String reason = failure.reason();
}
}
如果存在版本冲突,则抛出ElasticsearchException
:
IndexRequest request = new IndexRequest("posts", "doc", "1")
.source("field", "value")
.version(1);
try {
IndexResponse response = client.index(request, RequestOptions.DEFAULT);
} catch(ElasticsearchException e) {
if (e.status() == RestStatus.CONFLICT) {
}
}
如果将opType
设置为create
并且已存在具有相同索引、类型和ID的文档,则会发生相同的情况:
IndexRequest request = new IndexRequest("posts", "doc", "1")
.source("field", "value")
.opType(DocWriteRequest.OpType.CREATE);
try {
IndexResponse response = client.index(request, RequestOptions.DEFAULT);
} catch(ElasticsearchException e) {
if (e.status() == RestStatus.CONFLICT) {
}
}
GetRequest
需要以下参数:
GetRequest getRequest = new GetRequest(
"posts",
"doc",
"1");
posts
— 索引。doc
— 类型。1
— 文档id。可以选择提供以下参数:
request.fetchSourceContext(FetchSourceContext.DO_NOT_FETCH_SOURCE);
String[] includes = new String[]{"message", "*Date"};
String[] excludes = Strings.EMPTY_ARRAY;
FetchSourceContext fetchSourceContext =
new FetchSourceContext(true, includes, excludes);
request.fetchSourceContext(fetchSourceContext);
String[] includes = Strings.EMPTY_ARRAY;
String[] excludes = new String[]{"message"};
FetchSourceContext fetchSourceContext =
new FetchSourceContext(true, includes, excludes);
request.fetchSourceContext(fetchSourceContext);
request.storedFields("message");
GetResponse getResponse = client.get(request, RequestOptions.DEFAULT);
String message = getResponse.getField("message").getValue();
message
存储字段(要求字段分别存储在映射中)。request.routing("routing");
request.parent("parent");
request.preference("preference");
request.realtime(false);
realtime
标志设置为false
(默认为true
)。request.refresh(true);
false
)。request.version(2);
request.versionType(VersionType.EXTERNAL);
以下列方式执行GetRequest
时,客户端在继续执行代码之前等待返回GetResponse
:
GetResponse getResponse = client.get(getRequest, RequestOptions.DEFAULT);
执行GetRequest
也可以以异步方式完成,以便客户端可以直接返回,用户需要通过将请求和侦听器传递给异步get
方法来指定响应或潜在故障的处理方式:
client.getAsync(request, RequestOptions.DEFAULT, listener);
GetRequest
和执行完成时要使用的ActionListener
。异步方法不会阻塞并立即返回,完成后,如果执行成功完成,则使用onResponse
方法回调ActionListener
,如果失败则使用onFailure
方法。
get
的典型监听器看起来像:
ActionListener listener = new ActionListener() {
@Override
public void onResponse(GetResponse getResponse) {
}
@Override
public void onFailure(Exception e) {
}
};
onResponse
— 执行成功完成时调用。onFailure
— 在整个GetRequest失败时调用。返回的GetResponse
允许检索所请求的文档及其元数据和最终存储的字段。
String index = getResponse.getIndex();
String type = getResponse.getType();
String id = getResponse.getId();
if (getResponse.isExists()) {
long version = getResponse.getVersion();
String sourceAsString = getResponse.getSourceAsString();
Map sourceAsMap = getResponse.getSourceAsMap();
byte[] sourceAsBytes = getResponse.getSourceAsBytes();
} else {
}
Map
。byte[]
的形式检索文档。404
状态代码,但返回有效的GetResponse
而不是抛出异常,此类响应不包含任何源文档,并且其isExists
方法返回false
。当针对不存在的索引执行get
请求时,响应具有404
状态代码,抛出ElasticsearchException
,需要按如下方式处理:
GetRequest request = new GetRequest("does_not_exist", "doc", "1");
try {
GetResponse getResponse = client.get(request, RequestOptions.DEFAULT);
} catch (ElasticsearchException e) {
if (e.status() == RestStatus.NOT_FOUND) {
}
}
如果已请求特定文档版本,并且现有文档具有不同的版本号,则会引发版本冲突:
try {
GetRequest request = new GetRequest("posts", "doc", "1").version(2);
GetResponse getResponse = client.get(request, RequestOptions.DEFAULT);
} catch (ElasticsearchException exception) {
if (exception.status() == RestStatus.CONFLICT) {
}
}
引发的异常表示返回了版本冲突错误。
如果文档存在,则exists
API返回true
,否则返回false
。
它就像Get API一样使用GetRequest
,支持所有可选参数,由于exists()
只返回true
或false
,我们建议关闭获取_source
和任何存储的字段,以便请求稍微轻一点:
GetRequest getRequest = new GetRequest(
"posts",
"doc",
"1");
getRequest.fetchSourceContext(new FetchSourceContext(false));
getRequest.storedFields("_none_");
posts
— 索引。doc
— 类型。1
— 索引id。FetchSourceContext(false)
— 禁用提取_source
。storedFields("_none_")
— 禁用提取存储的字段。以下列方式执行GetRequest
时,客户端在继续执行代码之前等待返回boolean
:
boolean exists = client.exists(getRequest, RequestOptions.DEFAULT);
执行GetRequest
也可以以异步方式完成,以便客户端可以直接返回,用户需要通过将请求和侦听器传递给异步exists
方法来指定响应或潜在故障的处理方式:
client.existsAsync(getRequest, RequestOptions.DEFAULT, listener);
GetRequest
和执行完成时要使用的ActionListener
。异步方法不会阻塞并立即返回,完成后,如果执行成功完成,则使用onResponse
方法回调ActionListener
,如果失败则使用onFailure
方法。
exists
的典型侦听器如下所示:
ActionListener listener = new ActionListener() {
@Override
public void onResponse(Boolean exists) {
}
@Override
public void onFailure(Exception e) {
}
};
onResponse
— 执行成功完成时调用。onFailure
— 在整个GetRequest
失败时调用。DeleteRequest
没有参数。
DeleteRequest request = new DeleteRequest(
"posts",
"doc",
"1");
posts
— 索引。doc
— 类型。1
— 文档id。可以选择提供以下参数:
request.routing("routing");
request.parent("parent");
request.timeout(TimeValue.timeValueMinutes(2));
request.timeout("2m");
TimeValue
的超时。String
的超时。request.setRefreshPolicy(WriteRequest.RefreshPolicy.WAIT_UNTIL);
request.setRefreshPolicy("wait_for");
WriteRequest.RefreshPolicy
实例。String
。request.version(2);
request.versionType(VersionType.EXTERNAL);
以下列方式执行DeleteRequest
时,客户端在继续执行代码之前等待返回DeleteResponse
:
DeleteResponse deleteResponse = client.delete(
request, RequestOptions.DEFAULT);
执行DeleteRequest
也可以以异步方式完成,以便客户端可以直接返回,用户需要通过将请求和侦听器传递给异步删除方法来指定响应或潜在故障的处理方式:
client.deleteAsync(request, RequestOptions.DEFAULT, listener);
DeleteRequest
和执行完成时要使用的ActionListener
。异步方法不会阻塞并立即返回,完成后,如果执行成功完成,则使用onResponse
方法回调ActionListener
,如果失败则使用onFailure
方法。
delete
的典型侦听器如下所示:
listener = new ActionListener() {
@Override
public void onResponse(DeleteResponse deleteResponse) {
}
@Override
public void onFailure(Exception e) {
}
};
onResponse
— 执行成功完成时调用。onFailure
— 在整个DeleteRequest
失败时调用。返回的DeleteResponse
允许检索有关已执行操作的信息,如下所示:
String index = deleteResponse.getIndex();
String type = deleteResponse.getType();
String id = deleteResponse.getId();
long version = deleteResponse.getVersion();
ReplicationResponse.ShardInfo shardInfo = deleteResponse.getShardInfo();
if (shardInfo.getTotal() != shardInfo.getSuccessful()) {
}
if (shardInfo.getFailed() > 0) {
for (ReplicationResponse.ShardInfo.Failure failure :
shardInfo.getFailures()) {
String reason = failure.reason();
}
}
还可以检查文档是否被找到:
DeleteRequest request = new DeleteRequest("posts", "doc", "does_not_exist");
DeleteResponse deleteResponse = client.delete(
request, RequestOptions.DEFAULT);
if (deleteResponse.getResult() == DocWriteResponse.Result.NOT_FOUND) {
}
如果存在版本冲突,则抛出ElasticsearchException
:
try {
DeleteResponse deleteResponse = client.delete(
new DeleteRequest("posts", "doc", "1").version(2),
RequestOptions.DEFAULT);
} catch (ElasticsearchException exception) {
if (exception.status() == RestStatus.CONFLICT) {
}
}
说明此部分官方地址:
https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.4/_search_apis.html
SearchRequest用于与搜索文档、聚合、建议相关的任何操作,还提供了请求突出显示结果文档的方法。
最基本的形式,我们可以添加一个查询请求:
SearchRequest searchRequest = new SearchRequest();
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.matchAllQuery());
searchRequest.source(searchSourceBuilder);
可选参数
让我们先看看SearchRequest的一些可选参数:
SearchRequest searchRequest = new SearchRequest("posts");
将请求限制为索引posts
有几个其他有趣的可选参数:
searchRequest.routing("routing");
设置路由参数
searchRequest.indicesOptions(IndicesOptions.lenientExpandOpen());
设置IndicesOptions可以控制如何解析不可用的索引以及如何展开通配符表达式
searchRequest.preference("_local");
使用preference参数,例如,执行搜索以选择本地碎片。默认设置是在碎片之间随机分配。
大多数控制搜索行为的选项都可以在SearchSourceBuilder上设置,它或多或少地包含了Rest API的搜索请求体中的选项。
以下是一些常见的选择:
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(QueryBuilders.termQuery("user", "kimchy"));
sourceBuilder.from(0);
sourceBuilder.size(5);
sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
之后,SearchSourceBuilder只需要添加到SearchRequest:
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("posts");
searchRequest.source(sourceBuilder);
建立查询
搜索查询是使用QueryBuilder对象创建的。对于Elasticsearch的查询DSL支持的每个搜索查询类型,都存在一个QueryBuilder。
QueryBuilder可以使用它的构造函数创建:
MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder("user", "kimchy");
创建一个全文本匹配查询,在“user”字段上匹配文本“kimchy”
一旦创建,QueryBuilder对象提供方法来配置它创建的搜索查询的选项:
matchQueryBuilder.fuzziness(Fuzziness.AUTO);
matchQueryBuilder.prefixLength(3);
matchQueryBuilder.maxExpansions(10);
还可以使用QueryBuilders实用程序类创建QueryBuilder对象。这个类提供了可以使用连贯编程风格创建QueryBuilder对象的助手方法:
QueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("user", "kimchy")
.fuzziness(Fuzziness.AUTO)
.prefixLength(3)
.maxExpansions(10);
无论使用什么方法创建它,QueryBuilder对象都必须添加到SearchSourceBuilder中,如下所示:
searchSourceBuilder.query(matchQueryBuilder);
构建查询页面提供了所有可用搜索查询的列表,其中包含相应的QueryBuilder对象和QueryBuilders助手方法。
指定排序
SearchSourceBuilder允许添加一个或多个SortBuilder实例。有四种特殊的实现(Field-、Score-、GeoDistance-和ScriptSortBuilder)。
sourceBuilder.sort(new ScoreSortBuilder().order(SortOrder.DESC));
sourceBuilder.sort(new FieldSortBuilder("_id").order(SortOrder.ASC));
源过滤
默认情况下,搜索请求会返回文档’ _source ‘的内容,但是就像在Rest API中一样,您可以覆盖这种行为。例如,你可以完全关闭’ _source '检索:
sourceBuilder.fetchSource(false);
该方法还接受一个由一个或多个通配符模式组成的数组,以控制以更细粒度的方式包含或排除哪些字段:
String[] includeFields = new String[] {"title", "innerObject.*"};
String[] excludeFields = new String[] {"user"};
sourceBuilder.fetchSource(includeFields, excludeFields);
高亮查询
可以通过在SearchSourceBuilder上设置HighlightBuilder来突出显示搜索结果。通过添加一个或多个HighlightBuilder,可以为每个字段定义不同的突出显示行为。字段实例到HighlightBuilder。
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
HighlightBuilder highlightBuilder = new HighlightBuilder();
HighlightBuilder.Field highlightTitle =
new HighlightBuilder.Field("title");
highlightTitle.highlighterType("unified");
highlightBuilder.field(highlightTitle);
HighlightBuilder.Field highlightUser = new HighlightBuilder.Field("user");
highlightBuilder.field(highlightUser);
searchSourceBuilder.highlighter(highlightBuilder);
Rest API文档中详细解释了许多选项。Rest API参数(例如pre_tags)通常由同名的setter(例如#preTags(String…))更改。
聚合查询
通过首先创建适当的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);
使用建议
要向搜索请求添加建议,请使用可以从SuggestBuilders factory类轻松访问的SuggestionBuilder实现之一。建议生成器需要添加到顶级的SuggestBuilder中,其本身可以设置在SearchSourceBuilder中。
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:
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.profile(true);
一旦检索请求是执行相应的回应类别将包含分析结果。
异步执行
还可以以异步方式执行SearchRequest,以便客户机可以直接返回。用户需要通过向异步搜索方法传递请求和侦听器来指定如何处理响应或潜在故障:
client.searchAsync(searchRequest, RequestOptions.DEFAULT, listener);
执行的SearchRequest和执行完成时使用的ActionListener
异步方法不会阻塞,而是立即返回。一旦完成,如果执行成功完成,则使用onResponse方法调用ActionListener;如果执行失败,则使用onFailure方法调用它。失败场景和预期的异常与同步执行情况相同。
典型的搜索监听器是这样的:
ActionListener<SearchResponse> listener = new ActionListener<SearchResponse>() {
@Override
public void onResponse(SearchResponse searchResponse) {
}
@Override
public void onFailure(Exception e) {
}
};
onResponse当执行成功完成时,调用。
onFailure整个检索请求失败时调用。
SearchResponse
执行搜索返回的SearchResponse提供了关于搜索执行本身以及对返回文档的访问的详细信息。首先,有关于请求执行本身的有用信息,如HTTP状态码、执行时间或请求是否提前终止或超时:
RestStatus status = searchResponse.status();
TimeValue took = searchResponse.getTook();
Boolean terminatedEarly = searchResponse.isTerminatedEarly();
boolean timedOut = searchResponse.isTimedOut();
其次,响应还通过提供关于受搜索影响的碎片总数以及成功碎片和不成功碎片的统计信息,提供关于碎片级别上执行的信息。可能的故障也可以通过迭代shardsearchfailure数组来处理,如下面的例子所示:
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提供关于所有点击的全局信息,比如总点击数或最大得分:
TotalHits totalHits = hits.getTotalHits();
// the total number of hits, must be interpreted in the context of totalHits.relation
long numHits = totalHits.value;
// whether the number of hits is accurate (EQUAL_TO) or a lower bound of the total (GREATER_THAN_OR_EQUAL_TO)
TotalHits.Relation relation = totalHits.relation;
float maxScore = hits.getMaxScore();
嵌套在SearchHits是可以迭代的单个搜索结果:
SearchHit[] searchHits = hits.getHits();
for (SearchHit hit : searchHits) {
// do something with the SearchHit
}
SearchHit提供了对基本信息的访问,比如索引、文档ID和每次搜索命中的分数:
String index = hit.getIndex();
String id = hit.getId();
float score = hit.getScore();
此外,它还允许您以简单的JSON-String或键/值对映射的形式获取文档源。在此映射中,常规字段由字段名作为键值,并包含字段值。多值字段作为对象列表返回,嵌套对象作为另一个键/值映射返回。这些情况需要相应地进行判定:
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");
Retrieving Highlighting
检索高亮
如果需要,可以从结果中的每个SearchHit检索突出显示的文本片段。hit对象提供了从字段名到HighlightField实例的映射,每个实例包含一个或多个突出显示的文本片段:
SearchHits hits = searchResponse.getHits();
for (SearchHit hit : hits.getHits()) {
Map<String, HighlightField> highlightFields = hit.getHighlightFields();
HighlightField highlight = highlightFields.get("title");
Text[] fragments = highlight.fragments();
String fragmentString = fragments[0].string();
}
获取标题字段的高亮显示
获取一个或多个包含突出显示字段内容的片段
检索聚合
通过首先获取聚合树的根,即Aggregations对象,然后通过名称获取聚合,可以从SearchResponse检索聚合。
Aggregations aggregations = searchResponse.getAggregations();
Terms byCompanyAggregation = aggregations.get("by_company");
Bucket elasticBucket = byCompanyAggregation.getBucketByKey("Elastic");
Avg averageAge = elasticBucket.getAggregations().get("average_age");
double avg = averageAge.getValue();
注意,如果按名称访问聚合,需要根据请求的聚合类型指定聚合接口,否则会抛出ClassCastException:
Range range = aggregations.get("by_company");
会抛出一个异常,因为“by_company”是一个术语聚合,但我们试图将其检索为一个范围聚合。
还可以将所有聚合作为映射访问,映射由聚合名称作为键。在这种情况下,需要显式地转换到适当的聚合接口:
Map<String, Aggregation> aggregationMap = aggregations.getAsMap();
Terms companyAggregation = (Terms) aggregationMap.get("by_company");
还有getter返回所有顶级的聚合为一个列表:
List<Aggregation> aggregationList = aggregations.asList();
最后但并非最不重要的是,你可以迭代所有的聚合,然后决定如何进一步处理他们基于他们的类型:
for (Aggregation agg : aggregations) {
String type = agg.getType();
if (type.equals(TermsAggregationBuilder.NAME)) {
Bucket elasticBucket = ((Terms) agg).getBucketByKey("Elastic");
long numberOfDocs = elasticBucket.getDocCount();
}
}
Retrieving Suggestion
检索建议
要从SearchResponse获取建议,使用Suggest对象作为入口点,然后检索嵌套的建议对象:
Suggest suggest = searchResponse.getSuggest();
TermSuggestion termSuggestion = suggest.getSuggestion("suggest_user");
for (TermSuggestion.Entry entry : termSuggestion.getEntries()) {
for (TermSuggestion.Entry.Option option : entry) {
String suggestText = option.getText().string();
}
}
使用Suggest类来访问建议
可以通过名称检索建议。您需要将它们分配给建议类的正确类型(这里是TermSuggestion),否则将抛出ClassCastException
迭代建议条目
遍历一个条目中的选项
检索分析结果
使用getProfileResults()方法从SearchResponse检索分析结果。此方法为SearchRequest执行中涉及的每个碎片返回一个包含ProfileShardResult对象的映射。ProfileShardResult使用唯一标识配置文件结果所对应的碎片的键存储在映射中。
下面的示例代码演示了如何遍历每个碎片的所有分析结果:
Map<String, ProfileShardResult> profilingResults =
searchResponse.getProfileResults();
for (Map.Entry<String, ProfileShardResult> profilingResult : profilingResults.entrySet()) {
String key = profilingResult.getKey();
ProfileShardResult profileShardResult = profilingResult.getValue();
}
ProfileShardResult对象本身包含一个或多个查询配置文件结果,每个查询一个针对底层Lucene索引执行:
List<QueryProfileShardResult> queryProfileShardResults =
profileShardResult.getQueryProfileResults();
for (QueryProfileShardResult queryProfileResult : queryProfileShardResults) {
}
每个QueryProfileShardResult都允许访问详细的查询树执行,以ProfileResult对象列表的形式返回:
for (ProfileResult profileResult : queryProfileResult.getQueryResults()) {
String queryName = profileResult.getQueryName();
long queryTimeInMillis = profileResult.getTime();
List<ProfileResult> profiledChildren = profileResult.getProfiledChildren();
}
Rest API文档包含关于分析查询的更多信息,其中描述了查询分析信息。
QueryProfileShardResult还为Lucene收集器提供了对概要信息的访问:
CollectorResult collectorResult = queryProfileResult.getCollectorResult();
String collectorName = collectorResult.getName();
Long collectorTimeInMillis = collectorResult.getTime();
List<CollectorResult> profiledChildren = collectorResult.getProfiledChildren();
Rest API文档包含关于Lucene收集器的分析信息的更多信息。看到分析查询。
QueryProfileShardResult对象以与查询树执行非常相似的方式访问详细的聚合树执行:
AggregationProfileShardResult aggsProfileResults =
profileShardResult.getAggregationProfileResults();
for (ProfileResult profileResult : aggsProfileResults.getProfileResults()) {
String aggName = profileResult.getQueryName();
long aggTimeInMillis = profileResult.getTime();
List<ProfileResult> profiledChildren = profileResult.getProfiledChildren();
}
注:其它操作请查看https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.4/java-rest-high-supported-apis.html大同小异。
这里官方说的对于TransportClient,7.0不建议使用,8.0删除
IndexRequest构建情况是相同的,区别在于构建IndexResponse,transport使用RequestBuilder的相关prepare遗留方法去构建Response,rest直接使用client的对应方法去返回一个对应的Response。
比如transportClient.prepareBulk().get()直接变成client.bulk()得到的同样都是BulkResponse;
prepareSearch变成了search方法
不用Builder怎么执行——直接client执行
更多请查看博客:https://www.unclewang.info/learn/es/714/,https://segmentfault.com/a/1190000015138673