elasticsearch使用指南之Elasticsearch Document Get API详解、原理与示例

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: 本节首先罗列了文档Get API,并对GetRequest进行了详细分析,接着通过3个 示例展示Get API的使用,最后重点分析GET API 内部的实现机制(实时性、source过滤、路由、复制组内分片节点倾向性、刷新机制等)。

作者介绍:《RocketMQ技术内幕》作者,中间件兴趣圈微信公众号维护者。


本节将重点介绍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 listener)
    上述两个API,一个同步调用,一个异步调用,同步调用方法直接组装GetResponse 并返回,而异步方法通过回调ActionListener,并将执行结果(GetResponse )传入回调方法。

从中可以看出,Get API的核心是GetRequest 与RequestOptions,RequestOptions在上节中已详细说明,接下来将重点关注GetRequest。

1、GetRequest
GetRequest完整的类继承层次如下:
clipboard
其核心属性如图所示:
Elasticsearch_IndexRequest_

下面我们一一来介绍一下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、示例二:基于getRequest#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

/** Return an {@link Automaton} that matches the given pattern. */
    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过滤、路由、复制组内分片节点倾向性、刷新机制等)。

相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
目录
相关文章
|
27天前
|
存储 人工智能 自然语言处理
Elasticsearch Inference API增加对阿里云AI的支持
本文将介绍如何在 Elasticsearch 中设置和使用阿里云的文本生成、重排序、稀疏向量和稠密向量服务,提升搜索相关性。
66 14
Elasticsearch Inference API增加对阿里云AI的支持
|
2月前
|
JSON Go API
使用Go语言和Gin框架构建RESTful API:GET与POST请求示例
使用Go语言和Gin框架构建RESTful API:GET与POST请求示例
|
3月前
|
JSON API 开发者
GET方式请求速卖通平台API 接口:商品列表数据获取指南
速卖通商品列表数据接口(如 `aliexpress.item_search`)让开发者获取商品信息列表, 包括名称、价格等关键数据。接口支持按关键词、分类ID等条件获取商品列表及详细信息, 并可通过分页与排序优化展示效果。开发者需在速卖通开放平台注册并创建应用获取API密钥, 构建HTTP请求并处理JSON响应数据。[体验API](http://b.mrw.so/2Pv6Qu)。
|
4月前
|
JSON JavaScript 前端开发
若依修改,若依如何发送get和post请求,发送数据请求的写法,若依请求的API在src的api文件下,建立请求的第一步,在API中新建一个文件,第二步新建JavaScript文件
若依修改,若依如何发送get和post请求,发送数据请求的写法,若依请求的API在src的api文件下,建立请求的第一步,在API中新建一个文件,第二步新建JavaScript文件
|
5月前
|
人工智能 自然语言处理 搜索推荐
Elasticsearch 开放 inference API 增加了对 Azure OpenAI 嵌入的支持
【6月更文挑战第8天】Elasticsearch 推出开放 inference API,支持 Azure OpenAI 嵌入,强化搜索和数据分析能力。此更新使用户能灵活集成 AI 技术,实现智能精准搜索。Azure OpenAI 的语言理解能力优化了用户查询处理,提升搜索相关性。示例代码显示了如何结合两者处理查询。该创新提升数据检索效率,适用于智能客服和推荐系统,但也带来数据安全和模型准确性等挑战。这标志着搜索和数据分析领域的智能化新阶段,期待更多创新应用。未来,我们需要持续探索和完善,以发挥技术的最大潜力。
48 3
|
5月前
|
存储 缓存 Java
掌握Elasticsearch集群参数查询API
掌握Elasticsearch集群参数查询API
|
12天前
|
存储 安全 数据管理
如何在 Rocky Linux 8 上安装和配置 Elasticsearch
本文详细介绍了在 Rocky Linux 8 上安装和配置 Elasticsearch 的步骤,包括添加仓库、安装 Elasticsearch、配置文件修改、设置内存和文件描述符、启动和验证 Elasticsearch,以及常见问题的解决方法。通过这些步骤,你可以快速搭建起这个强大的分布式搜索和分析引擎。
29 5
|
1月前
|
存储 JSON Java
elasticsearch学习一:了解 ES,版本之间的对应。安装elasticsearch,kibana,head插件、elasticsearch-ik分词器。
这篇文章是关于Elasticsearch的学习指南,包括了解Elasticsearch、版本对应、安装运行Elasticsearch和Kibana、安装head插件和elasticsearch-ik分词器的步骤。
126 0
elasticsearch学习一:了解 ES,版本之间的对应。安装elasticsearch,kibana,head插件、elasticsearch-ik分词器。
|
2月前
|
NoSQL 关系型数据库 Redis
mall在linux环境下的部署(基于Docker容器),Docker安装mysql、redis、nginx、rabbitmq、elasticsearch、logstash、kibana、mongo
mall在linux环境下的部署(基于Docker容器),docker安装mysql、redis、nginx、rabbitmq、elasticsearch、logstash、kibana、mongodb、minio详细教程,拉取镜像、运行容器
mall在linux环境下的部署(基于Docker容器),Docker安装mysql、redis、nginx、rabbitmq、elasticsearch、logstash、kibana、mongo
|
3月前
|
数据可视化 Docker 容器
一文教会你如何通过Docker安装elasticsearch和kibana 【详细过程+图解】
这篇文章提供了通过Docker安装Elasticsearch和Kibana的详细过程和图解,包括下载镜像、创建和启动容器、处理可能遇到的启动失败情况(如权限不足和配置文件错误)、测试Elasticsearch和Kibana的连接,以及解决空间不足的问题。文章还特别指出了配置文件中空格的重要性以及环境变量中字母大小写的问题。
一文教会你如何通过Docker安装elasticsearch和kibana 【详细过程+图解】
下一篇
无影云桌面