专栏首页中间件兴趣圈Elasticsearch Document Get API详解、原理与示例

Elasticsearch Document Get API详解、原理与示例

本节将重点介绍ElasticSearch Doucment Get API(根据ID获取文档)。从《ElasticSearch Client详解》可知,ElasticSearch Get Rest Hign level Get Api声明如下:

  • public final GetResponse get(GetRequest getRequest, RequestOptions options) throws IOException
  • public final void getAsync(GetRequest getRequest, RequestOptions options, ActionListener<GetResponse> listener)

上述两个API,一个同步调用,一个异步调用,同步调用方法直接组装GetResponse 并返回,而异步方法通过回调ActionListener,并将执行结果(GetResponse )传入回调方法。从中可以看出,Get API的核心是GetRequest 与RequestOptions,RequestOptions在上节中已详细说明,接下来将重点关注GetRequest。

1、GetRequest

GetRequest完整的类继承层次如下:

其核心属性如图所示:

下面我们一一来介绍一下GetRequest的核心属性。

  • protected String index:索引库,对应关系型数据库的Database。
  • private String type:类型,对应关系型数据库的表。
  • private String id:文档ID,对应关系型数据库表中一行的主键ID。
  • private String routing:路由值。
  • private String parent:
  • private String preference:get请求选取执行节点的偏好,倾向性,在下文会详细介绍。
  • private String[] storedFields:显示的指定需要返回的字段,默认会返回_source中所有字段。
  • private FetchSourceContext fetchSourceContext:指定需要返回字段的上下文,是storedFields的补充与完善,支持通配符,下文会详细分析。
  • private boolean refresh = false:是否刷新。
  • boolean realtime = true:是否实时执行,默认为true。
  • private VersionType versionType = VersionType.INTERNAL:版本类型,已在《Elasticsearch Document Get API详解、原理与示例》中详细介绍
  • private long version = Versions.MATCH_ANY:数据版本,关于数据的版本管理,已在《Elasticsearch Document Get API详解、原理与示例》中详细介绍。

2、Get API Demo

1、示例一:

public static void testGet() {
       RestHighLevelClient client = EsClient.getClient();
       try {
           GetRequest request = new GetRequest("twitter", "_doc", "1");
           GetResponse result = client.get(request, RequestOptions.DEFAULT);
           System.out.println(result);
       } catch(Throwable e) {
           e.printStackTrace();
       } finally {
           EsClient.close(client);
       }
}

返回值:

{
       "_index":"twitter",
       "_type":"_doc",
       "_id":"1",
       "_version":3,
       "found":true,
       "_source":{
           "post_date":"2009-11-16T14:12:12",
           "message":"trying out Elasticsearch",
           "user":"dingw"
       }
}

2、示例二:基于storeFields进行source字段过滤

public static void testGet_storeFields() {
       RestHighLevelClient client = EsClient.getClient();
       try {
           GetRequest request = new GetRequest("twitter", "_doc", "1");
           request.storedFields("user");
           GetResponse result = client.get(request, RequestOptions.DEFAULT);           System.out.println(result);
       } catch(Throwable e) {
           e.printStackTrace();
       } finally {
           EsClient.close(client);
       }
   }

返回值:

{
   "_index":"twitter",
   "_type":"_doc",
   "_id":"1",
   "_version":3,
   "found":true
}

不符合预期,这是为什么呢?将在下文给出答案。

3、示例三:使用fetchSourceContext进行字段的过滤

public static void testGet_fetchSourceContext() {
       RestHighLevelClient client = EsClient.getClient();
       try {
           GetRequest request = new GetRequest("twitter", "_doc", "1");
               = new String[]{"message", "*date"};
           FetchSourceContext fsc = new FetchSourceContext(true, includes, null);
           request.fetchSourceContext(fsc);
           GetResponse result = client.get(request, RequestOptions.DEFAULT);
           System.out.println(result);
       } catch(Throwable e) {
           e.printStackTrace();
       } finally {
           EsClient.close(client);
       }
}

返回结果:

{
   "_index":"twitter",
   "_type":"_doc",
   "_id":"1",
   "_version":3,
   "found":true,
   "_source":{
       "post_date":"2009-11-16T14:12:12",
       "message":"trying out Elasticsearch"
   }
}

符合预期,只获取_source中的message与以date结尾的属性。

3、Get API 内部工作机制分析

3.1 实时性(Realtime)

默认情况下,get API是实时的,并且不会受到索引刷新频率的影响。如果一个文档被更新了(update),但是还没有刷新,那么get API将会发出一个刷新调用,以使文档可见。这也会使其他文档在上一次刷新可见后发生变化。如果不使用实时获取,可以将realtime设置false。

3.2 source字段过滤

按需返回所需字段,例如SQL语句select * 返回所有字段,可以通过select a.id,a.name返回所需字段。Elasticsearch提供了如下两种方式对_source字段进行过滤:

3.2.1 Stored Fields

get操作允许通过传递storedFields参数来指定一组需要获取储存的字段。如果所请求的字段没有被存储,它们将被忽略。请考虑以下映射:

PUT twitter
{
  "mappings": {
     "_doc": {
        "properties": {
           "counter": {
              "type": "integer",
              "store": false
           },
           "tags": {
              "type": "keyword",
              "store": true
           }
        }
     }
  }
}

注意映射在定义时,store字段,如果设置为false,就算指定storedFields=["counter"],也不会返回结果,也就时上述【示例2】没有返回 _source的原因。

3.2.2 FetchSourceContext

fetchSourceContext顾名思义,就是fetch source的上下文环境,提供更加完善的过滤逻辑,主要特性为支持include、exclude和支持通篇符过滤。

FetchSourceContext的构造函数:

public FetchSourceContext(boolean fetchSource, String[] includes, String[] excludes) {
       this.fetchSource = fetchSource;
       this.includes = includes == null ? Strings.EMPTY_ARRAY : includes;
       this.excludes = excludes == null ? Strings.EMPTY_ARRAY : excludes;
}

可以从两个维度includes(包含)、excludes(排除)。还支持带"*"的通配符,例如includes = ["msg*"]表示以msg开头的属性。通配符的解析逻辑:org.elasticsearch.common.regex#simpleMatchToAutomaton:

public static Automaton simpleMatchToAutomaton(String pattern) {
        List<Automaton> automata = new ArrayList<>();
        int previous = 0;
        for (int i = pattern.indexOf('*'); i != -1; i = pattern.indexOf('*', i + 1)) {
            automata.add(Automata.makeString(pattern.substring(previous, i)));
            automata.add(Automata.makeAnyString());
            previous = i + 1;
        }
        automata.add(Automata.makeString(pattern.substring(previous)));
        return Operations.concatenate(automata);
    }

3.3 路由机制

如果路由字段不是ID,请使用routing属性,更好的转发请求,否则会全部转发到所有的复制组,然后汇聚并返回。

3.4 倾向性(优先级、Preference)

Preference参数控制get请求对同一个复制组内多个副本的选择,默认情况下,该操作是在碎片副本之间进行随机分配的。一言以蔽之,preference的作用是同一个复制组中的路由规则。

其可选值:

  • _primary

操作将只在主分片上执行。

  • _local

如果可能的话,操作将更倾向于在本地分配的碎片上执行。当请求发到一个Node上,如果该Node上有对应的副本,则在该节点上执行,不会再将请求转发到其他节点。

  • 自定义字符串值

同一个自定义值,将会固定使用同一个分片(路由),该值通常会和会话信息绑定在一起,例如用户名,sessionId等,在应用层面对各

分片节点进行分流。

3.5 刷新机制

refersh如果设置为true,以便在get操作之前刷新相关分片,并使其可搜索,会刷新整个分片节点,此参数不建议使用,因为get操作默认是实时的,无性能损耗。

其他分布式特性、版本等是ElasticSearch的通用特性,就不再重复讲解了。

本节首先罗列了文档Get API,并对GetRequest进行了详细分析,接着通过3个 示例展示Get API的使用,最后重点分析GET API 内部的实现机制(实时性、source过滤、路由、复制组内分片节点倾向性、刷新机制等)。


本文分享自微信公众号 - 中间件兴趣圈(dingwpmz_zjj),作者:丁威

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-10-28

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • RocketMQ生产环境主题扩分片后遇到的坑

    消息组接到某项目组反馈,topic 在扩容后出现部分队列无法被消费者,导致消息积压,影响线上业务?

    丁威
  • Elasticsearch Multi Get、 Bulk API详解、原理与示例

    从上面所知,mget及批量获取文档,通过add方法添加多个Item,每一个item代表一个文件获取请求,其相关字段已在get API中详细介绍,这里就不做过多详...

    丁威
  • 源码分析Dubbo tps过滤器器实现原理

    本文将重点分析一下dubbo限流的另外一个方式,tps过滤器。 @Activate(group = Constants.PROVIDER, value = Co...

    丁威
  • 持续学习杂谈:阅读前言IT行业的知识结构最近的阅读列表阅读经验

    最近在阅读Bob大叔的新书——《Clean Architecture》(需要的同学可以在公众号后台回复数字1获取),感觉字字珠玑,值得反复阅读&品味。关于系统设...

    阿杜
  • 物联网时代-跟着Thingsboard学IOT架构-HTTP设备协议及API相关限制

    thingsboard GitHub: https://github.com/thingsboard/thingsboard

    sanshengshui
  • SAP标准培训课程C4C10学习笔记(三)第三单元

    C4C的Account List里能够直接在OWL(Object Work List)里看到每个账户的日程安排。

    Jerry Wang
  • 单细胞技术—基因测序新方向

    大数据文摘
  • 单细胞测序系列(1)--单细胞全基因组测序

    仅2018年,他的研究团队就发表了11篇单细胞测序方向文章,获得了单细胞测序领域的接连重要成果。他众多学术成果中,有40余篇论文发表在Cell, Nature,...

    用户6317549
  • 微服务的灾难(6) -- 康威定律和 KPI 冲突

    这里的 'are constrained to' 即是该定律的精髓所在。如果一个公司的组织架构已经基本成型了,那么基本上设计出的系统架构和其人员组织架构必然是一...

    iTesting
  • 腾讯开放 Marketing API,满足个性化社交广告营销

    纵观 Facebook、Twitter等国外社交网络的广告平台发展史,我们可以发现一个有趣的现象:当广告平台发展到一定的阶段时,都会将平台自身的广告能力通过 A...

    BestSDK

扫码关注云+社区

领取腾讯云代金券