Multi-Get API
Posted 冰
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Multi-Get API相关的知识,希望对你有一定的参考价值。
multiGet API并行地在单个http请求中执行多个get请求。
Multi-Get Request
MultiGetRequest构造函数为空,需要你添加`MultiGetRequest.Item`来配置要获取的内容:
MultiGetRequest request = new MultiGetRequest(); request.add(new MultiGetRequest.Item( "index", // Index "type", // Type "example_id")); //Document id //再添加一个 request.add(new MultiGetRequest.Item("index", "type", "another_id"));
可选参数
get API支持的可选参数,multiGet都支持。 您可以在每一项上设置这些大部分可选参数,为什么是大部分,因为有的参数是设置在主请求上,而不是每一项上:
//禁止获取source,默认为启用 request.add(new MultiGetRequest.Item("index", "type", "example_id") .fetchSourceContext(FetchSourceContext.DO_NOT_FETCH_SOURCE));
配置source包含指定的字段:
String[] includes = new String[] {"foo", "*r"}; String[] excludes = Strings.EMPTY_ARRAY; FetchSourceContext fetchSourceContext = new FetchSourceContext(true, includes, excludes); request.add(new MultiGetRequest.Item("index", "type", "example_id") .fetchSourceContext(fetchSourceContext));
配置source排除指定的字段:
String[] includes1 = Strings.EMPTY_ARRAY; String[] excludes1 = new String[] {"foo", "*r"}; FetchSourceContext fetchSourceContext1 = new FetchSourceContext(true, includes, excludes); request.add(new MultiGetRequest.Item("index", "type", "example_id") .fetchSourceContext(fetchSourceContext1));
//配置获取指定的stored字段,要求字段在mappings中是分开存储的(stored存储的原始字段,未经过分词的) request.add(new MultiGetRequest.Item("index", "type", "example_id") .storedFields("foo")); MultiGetResponse response = client.multiGet(request); MultiGetItemResponse item = response.getResponses()[0]; //获取foo的stored字段,要求字段和mappings中是分开存储的 String value = item.getResponse().getField("foo").getValue();
// Routing value request.add(new MultiGetRequest.Item("index", "type", "with_routing") .routing("some_routing")); // Parent value request.add(new MultiGetRequest.Item("index", "type", "with_parent") .parent("some_parent")); request.add(new MultiGetRequest.Item("index", "type", "with_version") .versionType(VersionType.EXTERNAL)// Version type .version(10123L));//Version
preference, realtime 和 refresh可以设置在主请求上,而不能设置在每项上
request.preference("some_preference");//preference值 request.realtime(false);//将realtime标志设置为false(默认为true) request.refresh(true);//在检索文档之前执行刷新(默认为false)
同步执行
//构建MultiGetRequest后,您可以用multiGet来同步执行: MultiGetResponse response1 = client.multiGet(request);
异步执行
异步执行多个get请求需要将MultiGetRequest实例和ActionListener实例传递给异步方法:
client.multiGetAsync(request, listener); //当MultiGetRequest执行完成时,ActionListener将被调用。
异步方法不会阻塞并会立即返回。 一旦请求完成,如果执行成功完成,则使用onResponse方法回调ActionListener,如果失败则使用onFailure方法。
MultiGetResponse的典型监听器如下所示:
ActionListener<MultiGetResponse> listener = new ActionListener<MultiGetResponse>() { @Override public void onResponse(MultiGetResponse response) { //执行成功完成时调用。 response以参数的形式提供。 } @Override public void onFailure(Exception e) { // 在失败的情况下调用。 引发的异常作为参数提供。 } };
Multi Get Response
返回的MultiGetResponse在getResponses中包含一个MultiGetItemResponse的列表,其顺序与请求的顺序相同。 如果获取成功,MultiGetItemResponse包含GetResponse,如果失败则包含MultiGetResponse.Failure。 成功看起来就像普通的GetResponse。
MultiGetItemResponse firstItem = response.getResponses()[0]; //assertNull(firstItem.getFailure());//getFailure返回null,由于这没有失败。 GetResponse firstGet = firstItem.getResponse();//getResponse返回GetResponse。 String index = firstItem.getIndex(); String type = firstItem.getType(); String id = firstItem.getId(); if (firstGet.isExists()) { long version = firstGet.getVersion(); String sourceAsString = firstGet.getSourceAsString();//以字符串形式获取文档 Map<String, Object> sourceAsMap = firstGet.getSourceAsMap();//以Map <String,Object>形式获取文档 byte[] sourceAsBytes = firstGet.getSourceAsBytes();//以字节数组的形式检索文档 } else { //处理未找到文档的方案。 请注意,虽然返回的响应具有404状态代码,但仍返回有效的GetResponse而不是抛出异常。 //此时此类响应不持有任何源文档,并且其isExists方法返回false。 }
当其中一个子请求执行不存在的索引时,getFailure将包含异常:
MultiGetItemResponse missingIndexItem = response.getResponses()[0]; assertNull(missingIndexItem.getResponse());//getResponse 是 null. //getFailure不为null,并且包含Exception,该异常实际上是一个ElasticsearchException Exception e = missingIndexItem.getFailure().getFailure(); ElasticsearchException ee = (ElasticsearchException) e; // TODO status is broken! fix in a followup //此时它的状态为NOT_FOUND。 要不是这是一个multi get,它其实就是一个HTTP 404。 assertEquals(RestStatus.NOT_FOUND, ee.status()); //getMessage解释了实际原因,没有这样的索引。 assertThat(e.getMessage(),containsString("reason=no such index"));
如果请求特定文档版本,并且现有文档具有不同的版本号,则会引发版本冲突:
MultiGetRequest request2 = new MultiGetRequest(); request2.add(new MultiGetRequest.Item("index", "type", "example_id") .version(1000L)); MultiGetResponse response2 = client.multiGet(request2); MultiGetItemResponse item2 = response.getResponses()[0]; assertNull(item.getResponse());//getResponse 是 null. //getFailure不为null,并且包含Exception,该异常实际上是一个ElasticsearchException Exception e = item.getFailure().getFailure(); ElasticsearchException ee = (ElasticsearchException) e; // TODO status is broken! fix in a followup //此时它的状态为NOT_FOUND。 要不是这是一个multi get,它就是一个HTTP 409 。 // assertEquals(RestStatus.CONFLICT, ee.status()); //getMessage解释了实际原因,即版本冲突。 assertThat(e.getMessage(), containsString("version conflict, current version [1] is " + "different than the one provided [1000]"));
官方文档:https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high-document-multi-get.html
以上是关于Multi-Get API的主要内容,如果未能解决你的问题,请参考以下文章
Android 插件化VirtualApp 源码分析 ( 目前的 API 现状 | 安装应用源码分析 | 安装按钮执行的操作 | 返回到 HomeActivity 执行的操作 )(代码片段
Express实战 - 应用案例- realworld-API - 路由设计 - mongoose - 数据验证 - 密码加密 - 登录接口 - 身份认证 - token - 增删改查API(代码片段