Java High Level REST Client 中文API(仅供参考)

1、初始化

兼容性

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,一旦集群中的所有节点都升级到新的主版本,客户端应该总是在最后更新。

Javadoc

https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.4/java-rest-high-supported-apis.html

Maven仓库

高级别Java REST客户端托管在Maven Central上,所需的最低Java版本为1.8

High Level REST Client与Elasticsearch具有相同的发布周期,将版本替换为想要的客户端版本。

如果你正在寻找SNAPSHOT版本,可以通过https://snapshots.elastic.co/maven/获取Elastic Maven Snapshot仓库。

Maven配置

以下是如何使用maven作为依赖关系管理器来配置依赖关系,将以下内容添加到pom.xml文件中


    org.elasticsearch.client
    elasticsearch-rest-high-level-client
    6.4.2

Gradle配置

以下是使用gradle作为依赖关系管理器配置依赖关系的方法,将以下内容添加到build.gradle文件中:

dependencies {
    compile 'org.elasticsearch.client:elasticsearch-rest-high-level-client:6.4.2'
}

Lucene Snapshot仓库

任何主要版本(如测试版)的最新版本可能都是基于Lucene Snapshot版本构建的,在这种情况下,你将无法解析客户端的Lucene依赖关系。

例如,如果要使用依赖于Lucene 7.0.0-snapshot-00142c96.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依赖于以下工件及其传递依赖性:

  • org.elasticsearch.client:elasticsearch-rest-client
  • org.elasticsearch:elasticsearch

初始化

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

RequestOptions

RestHighLevelClient中的所有API都接受RequestOptions,你可以用来不会改变Elasticsearch执行请求的的方式自定义请求。例如,你可以在此处指定NodeSelector来控制哪个节点接收请求,有关自定义选项的更多示例,请参阅低级别客户端文档。

2、Index API

索引请求

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");
  • 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提供的操作类型:可以为createupdate(默认)。
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) {
        
    }
}

3、Get API

Get请求

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");
  • 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失败时调用。

Get响应

返回的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) {
        
    }
}

引发的异常表示返回了版本冲突错误。

4、Exists API

如果文档存在,则existsAPI返回true,否则返回false

Exists请求

它就像Get API一样使用GetRequest,支持所有可选参数,由于exists()只返回truefalse,我们建议关闭获取_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失败时调用。

5、Delete API

Delete请求

DeleteRequest没有参数。

DeleteRequest request = new DeleteRequest(
        "posts",    
        "doc",      
        "1");
  • posts — 索引。
  • doc — 类型。
  • 1 — 文档id。

可选参数

可以选择提供以下参数:

request.routing("routing");
  • 路由值。
request.parent("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失败时调用。

Delete响应

返回的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

6、Search API

Search Request

SearchRequest用于与搜索文档、聚合、建议相关的任何操作,还提供了请求突出显示结果文档的方法。

最基本的形式,我们可以添加一个查询请求:

SearchRequest searchRequest = new SearchRequest(); 
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); 
searchSourceBuilder.query(QueryBuilders.matchAllQuery()); 
searchRequest.source(searchSourceBuilder); 
  • 创建SeachRequest。如果没有参数,则运行所有索引。
  • 大多数搜索参数被添加到SearchSourceBuilder。它为进入搜索请求体的所有内容提供。
  • 向SearchSourceBuilder添加一个match_all查询。
  • 将SearchSourceBuilder添加到SeachRequest中。

Optional arguments

可选参数

让我们先看看SearchRequest的一些可选参数:

SearchRequest searchRequest = new SearchRequest("posts"); 

将请求限制为索引posts

有几个其他有趣的可选参数:

searchRequest.routing("routing"); 

设置路由参数

searchRequest.indicesOptions(IndicesOptions.lenientExpandOpen()); 

设置IndicesOptions可以控制如何解析不可用的索引以及如何展开通配符表达式

searchRequest.preference("_local"); 

使用preference参数,例如,执行搜索以选择本地碎片。默认设置是在碎片之间随机分配。

SearchSourceBuilder

大多数控制搜索行为的选项都可以在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。
  • 设置查询。成为任何类型的QueryBuilder
  • 设置from选项,该选项确定要开始搜索的结果索引。默认值为0。
  • 设置确定要返回的搜索结果数量的大小选项。默认为10。
  • 设置一个可选的超时,控制允许搜索的时间。

之后,SearchSourceBuilder只需要添加到SearchRequest:

SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("posts");
searchRequest.source(sourceBuilder);

Building query

建立查询

搜索查询是使用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助手方法。

Specifying Sorting

指定排序

SearchSourceBuilder允许添加一个或多个SortBuilder实例。有四种特殊的实现(Field-、Score-、GeoDistance-和ScriptSortBuilder)。

sourceBuilder.sort(new ScoreSortBuilder().order(SortOrder.DESC)); 
sourceBuilder.sort(new FieldSortBuilder("_id").order(SortOrder.ASC));  
  • 按_score降序排序(默认)
  • 还可以按_id字段升序排序

Source filtering

源过滤

默认情况下,搜索请求会返回文档’ _source ‘的内容,但是就像在Rest API中一样,您可以覆盖这种行为。例如,你可以完全关闭’ _source '检索:

sourceBuilder.fetchSource(false);

该方法还接受一个由一个或多个通配符模式组成的数组,以控制以更细粒度的方式包含或排除哪些字段:

String[] includeFields = new String[] {"title", "innerObject.*"};
String[] excludeFields = new String[] {"user"};
sourceBuilder.fetchSource(includeFields, excludeFields);

Requesting Highlighting

高亮查询

可以通过在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);
  • 创建一个新的HighlightBuilder
  • 为标题栏创建一个高光栏
  • 设置字段高亮字体
  • 将字段高光添加到高光生成器

Rest API文档中详细解释了许多选项。Rest API参数(例如pre_tags)通常由同名的setter(例如#preTags(String…))更改。

Requesting Aggregation

聚合查询

通过首先创建适当的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 Suggestion

使用建议

要向搜索请求添加建议,请使用可以从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);
  • 为用户字段和文本kmichy创建一个新的termtionbuilder
  • 添加建议生成器并将其命名为suggest_user

Profiling Queries and Aggregationsedit

分析查询和聚合

配置文件API可用于配置特定搜索请求的查询和聚合的执行。为了使用它,配置文件标志必须设置为真在SearchSourceBuilder:

SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.profile(true);

一旦检索请求是执行相应的回应类别将包含分析结果。

Asynchronous execution

异步执行

还可以以异步方式执行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

执行搜索返回的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
}

Retrieving SearchHits

检索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();
}

获取标题字段的高亮显示

获取一个或多个包含突出显示字段内容的片段

Retrieving Aggregations

检索聚合

通过首先获取聚合树的根,即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();
  • 得到by_company聚合
  • 得到Elastic对应的Bucket
  • 从该bucket获取average_age子聚合

注意,如果按名称访问聚合,需要根据请求的聚合类型指定聚合接口,否则会抛出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

  • 迭代建议条目

  • 遍历一个条目中的选项

Retrieving Profiling Results

检索分析结果

使用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(); 
}
  • 从SearchResponse检索ProfileShardResult的地图
  • 如果键是已知的,那么可以通过shard的键检索分析结果,否则遍历所有分析结果可能更简单
  • 检索标识ProfileShardResult属于哪个碎片的键
  • 检索给定碎片的ProfileShardResult

ProfileShardResult对象本身包含一个或多个查询配置文件结果,每个查询一个针对底层Lucene索引执行:

List<QueryProfileShardResult> queryProfileShardResults =
        profileShardResult.getQueryProfileResults(); 
for (QueryProfileShardResult queryProfileResult : queryProfileShardResults) { 

}
  • 检索QueryProfileShardResult的列表
  • 遍历每个QueryProfileShardResult

每个QueryProfileShardResult都允许访问详细的查询树执行,以ProfileResult对象列表的形式返回:

for (ProfileResult profileResult : queryProfileResult.getQueryResults()) { 
    String queryName = profileResult.getQueryName(); 
    long queryTimeInMillis = profileResult.getTime(); 
    List<ProfileResult> profiledChildren = profileResult.getProfiledChildren(); 
}
  • 遍历配置文件结果
  • 检索Lucene查询的名称
  • 检索在millis中执行Lucene查询所花费的时间
  • 检索子查询的概要结果(如果有的话)

Rest API文档包含关于分析查询的更多信息,其中描述了查询分析信息。

QueryProfileShardResult还为Lucene收集器提供了对概要信息的访问:

CollectorResult collectorResult = queryProfileResult.getCollectorResult();  
String collectorName = collectorResult.getName();  
Long collectorTimeInMillis = collectorResult.getTime(); 
List<CollectorResult> profiledChildren = collectorResult.getProfiledChildren(); 
  • 检索Lucene收集器的分析结果
  • 检索Lucene收集器的名称
  • 检索在millis中执行Lucene收集器所花费的时间
  • 检索子收集器的配置文件结果(如果有)

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(); 
}
  • 检索AggregationProfileShardResult
  • 遍历聚合配置文件结果
  • 检索聚合的类型(对应于用于执行聚合的Java类)
  • 检索在millis中执行Lucene收集器所花费的时间
  • 检索子聚合的配置文件结果(如果有的话)

注:其它操作请查看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

你可能感兴趣的:(springboot高级,Elasticsearch)