Elasticsearch硬核入门教程(2022最全)

2023-11-03

Java全能学习+面试指南:https://javaxiaobear.cn

1、Elasticsearch概述

1、什么是Elasticsearch

The Elastic Stack, 包括 Elasticsearch、Kibana、Beats 和 Logstash(也称为 ELK Stack)。能够安全可靠地获取任何来源、任何格式的数据,然后实时地对数据进行搜索、分析和可视化。Elaticsearch,简称为ES, ES是一个开源的高扩展的分布式全文搜索引擎,是整个Elastic Stack技术栈的核心。它可以近乎实时的存储、检索数据;本身扩展性很好,可以扩展到上百台服务器,处理PB级别的数据。

2、全文搜索引擎

Google,百度类的网站搜索,它们都是根据网页中的关键字生成索引,我们在搜索的时候输入关键字,它们会将该关键字即索引匹配到的所有网页返回;还有常见的项目中应用日志的搜索等等。对于这些非结构化的数据文本,关系型数据库搜索不是能很好的支持。

一般传统数据库,全文检索都实现的很鸡肋,因为一般也没人用数据库存文本字段。进行全文检索需要扫描整个表,如果数据量大的话即使对SQL的语法优化,也收效甚微。建立了索引,但是维护起来也很麻烦,对于 insert 和 update 操作都会重新构建索引。

基于以上原因可以分析得出,在一些生产环境中,使用常规的搜索方式,性能是非常差的:

  • 搜索的数据对象是大量的非结构化的文本数据。

  • 文件记录量达到数十万或数百万个甚至更多。

  • 支持大量基于交互式文本的查询。

  • 需求非常灵活的全文搜索查询。

  • 对高度相关的搜索结果的有特殊需求,但是没有可用的关系数据库可以满足。

  • 对不同记录类型、非文本数据操作或安全事务处理的需求相对较少的情况。

为了解决结构化数据搜索和非结构化数据搜索性能问题,我们就需要专业,健壮,强大的全文搜索引擎,这里说到的全文搜索引擎指的是目前广泛应用的主流搜索引擎。它的工作原理是计算机索引程序通过扫描文章中的每一个词,对每一个词建立一个索引,指明该词在文章中出现的次数和位置,当用户查询时,检索程序就根据事先建立的索引进行查找,并将查找的结果反馈给用户的检索方式。这个过程类似于通过字典中的检索字表查字的过程。

3、Elasticsearch And Solr

Lucene是Apache软件基金会Jakarta项目组的一个子项目,提供了一个简单却强大的应用程式接口,能够做全文索引和搜寻。在Java开发环境里Lucene是一个成熟的免费开源工具。就其本身而言,Lucene是当前以及最近几年最受欢迎的免费Java信息检索程序库。但Lucene只是一个提供全文搜索功能类库的核心工具包,而真正使用它还需要一个完善的服务框架搭建起来进行应用。

目前市面上流行的搜索引擎软件,主流的就两款:Elasticsearch和Solr,这两款都是基于Lucene搭建的,可以独立部署启动的搜索引擎服务软件。由于内核相同,所以两者除了服务器安装、部署、管理、集群以外,对于数据的操作 修改、添加、保存、查询等等都十分类似。

4、Elasticsearch Or Solr

Elasticsearch和Solr都是开源搜索引擎,那么我们在使用时该如何选择呢?

  • Google 搜索趋势结果表明,与 Solr 相比, Elasticsearch 具有很大的吸引力,但这并不意味着 Apache Solr 已经死亡。虽然有些人可能不这么认为,但 Solr 仍然是最受欢迎的搜索引擎之一,拥有强大的社区和开源支持。

  • 与 Solr 相比, Elasticsearch 易于安装且非常轻巧。此外,你可以在几分钟内安装并运行Elasticsearch 。但是,如果 Elasticsearch 管理不当,这种易于部署和使用可能会成为一个问题。基于 JSON 的配置很简单,但如果要为文件中的每个配置指定注释,那么它不适合您。总的来说,如果你的应用使用 的是 JSON ,那么 Elasticsearch 是一个更好的选择。否则,请使用 Solr ,因为它的 schema.xml 和 solrconfig.xml 都有很好的文档记录。

  • Solr 拥有更大,更成熟的用户,开发者和贡献者社区。 ES 虽拥有的规模较小但活跃的用户社区以及不断增长的贡献者社区。Solr贡献者和提交者来自许多不同的组织,而 Elasticsearch 提交者来自单个公司。

  • Solr 更成熟,但 ES 增长迅速,更稳定。

  • Solr 是一个非常有据可查的产品,具有清晰的示例和 API 用例场景。 Elasticsearch 的文档组织良好,但它缺乏好的示例和清晰的配置说明。

那么,到底是Solr 还是 Elasticsearch?

  • 由于易于使用, Elasticsearch 在新开发者中更受欢迎。一个下载和一个命令就可以启动一切。

  • 如果除了搜索文本之外还需要它来处理分析查询, Elasticsearch 是更好的选择

  • 如果需要分布式索引,则需要选择 Elasticsearch 。对于需要良好可伸缩性和 以及 性能分布式环境 Elasticsearch 是更好的选择。

  • Elasticsearch 在开源日志管理用例中占据主导地位,许多组织在 Elasticsearch 中索引它们的日志以使其可搜索。

  • 如果你喜欢监控和指标,那么请使用Elasticsearch ,因为相对于Solr,Elasticsearch 暴露了更多的关键指标

2、Elasticsearch入门

1、Elasticsearch 安装

1、下载

Elasticsearch 的官方地址: https://www.elastic.co/cn/

下载地址:https://www.elastic.co/cn/downloads/past-releases#elasticsearch

Elasticsearch 分为 Linux 和 WindowWindows版本,基于我们主要学习的是 ElasticElasticsearch 的 Java客户端的使用,所以 课程 中使用的是安装较为简便的 WindowWindows版本 。

2、安装

Windows版的 ElasticElasticsearch 的安装很简单,解压即安装完毕,解压后的 ElasticElasticsearch 的 目录结构如下

目录 含义
bin 可执行脚本目录
config 配置目录
jdk 内置JDK 目录
lib 类库
logs 日志目录
modules 模块目录
plugins 插件目录

解压后,进入bin 文件目录,点击 elasticsearch.bat 文件启动 ES 服务

注意:

  • 9300 端口为 Elastic s earch 集群间组件的通信端口,

  • 9200 端口为浏览器访问的 http协议 RESTful 端口。

打开浏览器(推荐使用谷歌浏览器),输入地址:http://localhost:9200 ,测试结果

3、问题解决

  • ElasticSearch 是使用 java 开发的,且 7.13.2版本的 ES 需要 JDK 版本 1.8 以上,默认安装包带有 jdk 环境,如果系统配置 JAVA_HOME ,那么使用系统默认的 JDK ,如果没有配置使用自带的 JDK ,一般建议使用系统配置的 JDK 。

  • 双击启动窗口闪退,通过路径访问追踪错误,如果是“空间不足”,请修改config/jvm.options 配置文件

    设置 JVM 初始内存为 1G 。此值可以设置与 Xmx 相同,以避免每次垃圾回收完成后 JVM 重新分配内存

    Xms represents the initial size of total heap space

    设置 JVM 最大可用内存为 1G

    Xmx represents the maximum size of total heap space

    Xms1g Xmx1g

2、基本操作

1、RESTful

REST指的是一组架构约束条件和原则。满足这些约束条件和原则的应用程序或设计就是 RESTful 。 Web 应用程序最重要的 REST 原则是,客户端和服务器之间的交互在请求之间是无状态的。从客户端到服务器的每个请求都必须包含理解请求所必需的信息。如果服务器在请求之间的任何时间点重启,客户端不会得到通知。此外,无状态请求可以由任何可用服务器回答,这十分适合云计算之类的环境。客户端可以缓存数据以改进性能。

在服务器端,应用程序状态和功能可以分为各种资源。资源是一个有趣的概念实体,它向客户端公开。资源的例子有:应用程序对象、数据库记录、算法等等。每个资源都使用 URI(Universal Resource Identifier) 得到一个唯一的地址。所有资源都共享统一的接口,以便在客户端和服务器之间传输状态。使用的是标准的 HTTP 方法,比如 GET 、 PUT 、 POST 和DELETE 。

在REST 样式的 Web 服务中,每个资源都有一个地址。资源本身都是方法调用的目标,方法列表对所有资源都是一样的。这些方法都是标准方法,包括 HTTP GET 、 POST 、PUT 、 DELETE ,还可能包括 HEAD 和 OPTIONS 。简单的理解就是,如果想要访问互联网上的资源,就必须向资源所在的服务器发出请求,请求体中必须包含资源的网络路径, 以及对资源进行的操作 增删改查 。

2、Postman安装

如果直接通过浏览器向Elasticsearch 服务器发请求,那么需要在发送的请求中包含HTTP 标准的方法,而 HTTP 的大部分特性且仅支持 GET 和 POST 方法。所以为了能方便地进行客户端的访问,可以使用 Postman 软件  Postman是一款强大 的 网页调试工具,提供功能强大的 Web API 和 HTTP 请求调试。软件功能强大,界面简洁明晰、操作方便快捷,设计得很人性化。 Postman 中文版能够发送任何类型的 HTTP 请求 (GET, POST, PUT..) PUT..),不仅能够表单提交,且可以附带任意类型请求体。

Postman官网: https://www.getpostman.com Postman下载 https://www.getpostman.com/apps

3、数据格式

Elasticsearch是面向文档型数据库,一条数据在这里就是一个文档。 为了方便大家理解,我们将 Elastic s earch 里 存储 文档 数据和关系型数据库 MySQL 存储数据的概念进行一个类比

ES里的 Index 可以看做一个库,而 Types 相当于表, Documents 则相当于表的行。这里Types 的概念已经被逐渐弱化, Elasticsearch 6.X 中,一个 index 下已经只能包含一个type Elasticsearch 7.X 中 , Type 的概念已经被删除了。

4、HTTP操作

1、索引操作

1、创建索引

对比关系型数据库,创建索引就等同于创建数据库

在Postman 中,向 ES 服务器发 PUT 请求 http://127.0.0.1:9200/start

请求后,服务器返回响应

 " 【响应结果】 : true, # true 操作成功
 "shards_ 【分片结果】 : true, # 分片操作成功
 " 【索引名称】 : "
 # 注意:创建索引库的分片数默认 1 片,在 7.0.0 之前的 Elasticsearch 版本中,默认 5 片

如果重复添加索引,会返回错误信息

2、查看索引

在Postman 中,向 ES 服务器发 GET 请求 http://127.0.0.1:9200/_cat/indices?v

这里请求路径中的 _cat 表示查看的意思, indices 表示索引,所以整体含义就是查看当前 ES服务器中的所有索引,就好像 MySQL 中的 show tables 的感觉,服务器响应结果如下

3、查看单个索引

在Postman 中,向 ES 服务器发 GET 请求 http://127.0.0.1:9200/start

查看索引向ES 服务器发送的请求路径和创建索引是一致的。但是 HTTP 方法不一致。这里可以体会一下 RESTful 的意义,请求后,服务器响应结果如下:

 {
     "start"【索引名】: {
         "aliases"【别名】: {},
         "mappings"【映射】: {},
         "settings"【设置】: {
             "index"【设置-索引】: {
                 "routing": {
                     "allocation": {
                         "include": {
                             "_tier_preference": "data_content"
                         }
                     }
                 },
                 "number_of_shards"【设置-索引-主分片数量】: "1",
                 "provided_name"【名称】: "start",
                 "creation_date"【创建时间】: "1624440317651",
                 "number_of_replicas"【设置-索引-副分片数量】: "1",
                 "uuid"【唯一标识】: "5tI3rmvvQsKJISZ8GDR-YQ",
                 "version"【设置-索引-版本】: {
                     "created": "7130299"
                 }
             }
         }
     }
 }

4、删除索引

在Postman 中,向 ES 服务器发 DELETE 请求 http://127.0.0.1:9200/start

重新访问索引时,服务器返回响应:索引不存在

2、文档操作

1、创建文档

索引已经创建好了,接下来我们来创建文档,并添加数据。这里的文档可以类比为关系型数据库中的表数据,添加的数据格式为 JSON 格式

在Postman 中,向 ES 服务器发 POST 请求 http://127.0.0.1:9200/start/doc

此处发送请求的方式必须为POST ,不能是 PUT ,否则会发生错误

 {
     "_index"【索引】: "start",
     "_type"【类型-文档】: "doc",
     "_id"【唯一标识】: "iY9GOHoBucAyibLJ1Bbq",#可以类比为 MySQL 中的主键,随机生成
     "_version"【版本号】: 1,
     "result"【结果】: "created", #这里的 create 表示创建成功
     "_shards"【分片】: {
         "total"【分片-总数】: 2,
         "successful"【分片-成功】: 1,
         "failed"【分片-s】: 0
     },
     "_seq_no": 1,
     "_primary_term": 1
 }

上面的数据创建后,由于没有指定数据唯一性标识(ID ),默认情况下 ES 服务器会随机生成一个 。

如果想要自定义唯一性标识,需要在创建时指定http://127.0.0.1:9200/start/doc/1 or http://127.0.0.1:9200/start/_doc/1

此处需要注意:如果增加数据时明确数据主键,那么请求方式也可以为PUT

2、查看文档

查看文档时,需要指明文档的唯一性标识,类似于MySQL 中数据的主键查询

在Postman 中,向 ES 服务器发 GET 请求 http://127.0.0.1:9200/start/_doc/1

查询成功后,服务器响应结果:

 {
     "_index"【索引】: "start",
     "_type"【文档类型】: "_doc",
     "_id": "1",
     "_version": 1,
     "_seq_no": 2,
     "_primary_term": 2,
     "found"【查询结果】: true,# true 表示查找到, false 表示未查找到
     "_source"【文档源信息】: {
         "title": "小米手机",
         "category": "小米",
         "images": "www.xiaobear.cn",
         "price": 3999.00
     }
 }

3、修改文档

和新增文档一样,输入相同的URL 地址请求,如果请求体变化,会将原有的数据内容覆盖 在Postman 中,向 ES 服 务器发 POST 请求 http://127.0.0.1:9200/start/_doc/1

请求体内容为:

 {
     "title":"华为手机",
     "category":"小米",
     "images":"www.xiaobear.cn",
     "price":4999.00
 }

修改成功后,服务器响应结果:

 {
     "_index": "start",
     "_type": "_doc",
     "_id": "1",
     "_version"【版本】: 2,
     "result"【结果】: "updated",# updated 表示数据被更新
     "_shards": {
         "total": 2,
         "successful": 1,
         "failed": 0
     },
     "_seq_no": 3,
     "_primary_term": 2
 }

4、修改字段

修改数据时,也可以只修改某一给条数据的局部信息

在Postman 中,向 ES 服务器发 POST 请求 http://127.0.0.1:9200/start/_update/1

请求体内容为:

 {
 "doc": {
     "price":5000.00
     }
 }

修改成功后,服务器响应结果:

根据唯一性标识,查询文档数据,文档数据已经更新

5、删除文档

删除一个文档不会立即从磁盘上移除,它只是被标记成已删除(逻辑删除)。

在Postman 中,向 ES 服务器发 DELETE 请求 http://127.0.0.1:9200/start/_doc/1

删除成功,服务器响应结果:

version:对数据的操作,都会更新版本

删除后再查询当前文档信息

如果删除一个并不存在的文档

6、条件删除文档

一般删除数据都是根据文档的唯一性标识进行删除,实际操作时,也可以根据条件对多条数据进行删除

首先分别增加多条数据:

{
    "title":"小米手机",
    "category":"小米",
    "images":"www.xiaobear.cn",
    "price":3999.00
}
{
    "title":"华为手机",
    "category":"华为",
    "images":"www.xiaobear.cn",
    "price":3999.00
}

向ES 服务器发 POST 请求 http://127.0.0.1:9200/start/_delete_by_query

请求体内容为:

{
    "query":{
        "match":{
            "price": 3999.00
        }
    }
}

删除成功后,服务器响应结果:

3、映射操作

有了索引库,等于有了数据库中的database 。

接下来就需要建索引库(index)中的映射了,类似于数据库 (database)中的表结构 (table)。创建数据库表需要设置字段名称,类型,长度,约束等;索引库也一样,需要知道这个类型下有哪些字段,每个字段有哪些约束信息,这就叫做映射 (mapping)。

1、创建映射

在Postman 中,向 ES 服务器发 PUT 请求http://127.0.0.1:9200/user/_mapping

请求内容为:

{
    "properties":{
        "name":{
            "type": "text",
            "index": true
        },
        "sex":{
            "type": "keyword",
            "index": true
        },
        "phone":{
            "type": "keyword",
            "index": false
        }
    }
}

服务器的响应

映射数据说明

  • 字段名:任意填写,下面指定许多属性,例如: title 、 subtitle 、 images 、 price

  • type :类型 Elasticsearch 中支持的数据类型非常丰富,说几个关键的:

    • 基本数据类型:long 、 integer 、 short 、 byte 、 double 、 float 、 half_float

    • 浮点数的高精度类型:scaled_float

    • text:可分词

    • keyword:不可分词,数据会作为完整字段进行匹配

    • String 类型,又分两种:

    • Numerical :数值类型,分两类

    • Date :日期类型

    • Array :数组类型

    • Object :对象

  • index :是否索引,默认为 true ,也就是说你不进行任何配置,所有字段都会被索引。

    • true:字段会被索引,则可以用来进行搜索

    • false:字段不会被索引,不能用来搜索

  • store :是否将数据进行独立存储,默认为 false

    原始的文本会存储在_source 里面,默认情况下其他提取出来的字段都不是独立存储的,是从 _source 里面提取出来的。当然你也可以独立的存储某个字段,只要设置"store": true 即可,获取独立存储的字段要比从 _source 中解析快得多,但是也会占用更多的空间,所以要根据实际业务需求来设置。

  • analyzer :分词器,这里的 ik_max_word 即使用 ik 分词器

2、查看映射

在Postman 中,向 ES 服务器发 GET 请求http://127.0.0.1:9200/user/_mapping

3、索引映射关联

在Postman 中,向 ES 服务器发 PUT 请求 http://127.0.0.1:9200/user1

3、Java API

1、环境准备

  1. 创建maven项目

  2. 导入相关依赖

        <dependencies>
            <dependency>
                <groupId>org.elasticsearch</groupId>
                <artifactId>elasticsearch</artifactId>
                <version>7.8.0</version>
            </dependency>
            <!--es的客户端-->
            <dependency>
                <groupId>org.elasticsearch.client</groupId>
                <artifactId>elasticsearch-rest-high-level-client</artifactId>
                <version>7.8.0</version>
            </dependency>
            <dependency>
                <groupId>org.apache.logging.log4j</groupId>
                <artifactId>log4j-core</artifactId>
                <version>2.14.1</version>
            </dependency>
            <dependency>
                <groupId>org.apache.logging.log4j</groupId>
                <artifactId>log4j-api</artifactId>
                <version>2.14.1</version>
            </dependency>
            <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-databind</artifactId>
                <version>2.12.4</version>
            </dependency>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.13.1</version>
                <scope>test</scope>
            </dependency>
        </dependencies>
    
  3. 创建测试

    public class ElasticSearchTest {
    
        public static void main(String[] args) throws IOException {
            //9200 端口为 Elastic s earch 的 Web 通信端口 localhost 为启动 ES 服务的主机名
            RestHighLevelClient client = new RestHighLevelClient(
                    RestClient.builder(new HttpHost("localhost",9200)));
            client.close();
        }
    }
    

    没有任何输出或报错信息即是成功

2、索引操作

1、创建索引

ES服务器正常启动后,可以通过 Java API 客户端对象对 ES 索引进行操作

public class ElasticsearchDocCreate {

    public static void main(String[] args) throws IOException {
        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(new HttpHost("localhost",9200)));
        //创建索引
        CreateIndexRequest request = new CreateIndexRequest("user");
        CreateIndexResponse response = client.indices().create(request, RequestOptions.DEFAULT);
        //创建索引的响应状态
        boolean acknowledged = response.isAcknowledged();
        System.out.println("响应状态为:" + acknowledged);
        client.close();
    }
}

输出结果

2、查看索引

public class ElasticsearchDocSearch {

    public static void main(String[] args) throws IOException {
        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(new HttpHost("localhost",9200)));
        //查询索引
        GetIndexRequest request = new GetIndexRequest("user");
        GetIndexResponse response = client.indices().get(request, RequestOptions.DEFAULT);
        //查询索引的响应状态
        System.out.println(response);
        System.out.println(response.getSettings());
        System.out.println(response.getAliases());
        System.out.println(response.getMappings());
        client.close();
    }
}

输出结果

3、删除索引

public class ElasticsearchDocDelete {

    public static void main(String[] args) throws IOException {
        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(new HttpHost("localhost",9200)));
        //删除索引
        DeleteIndexRequest request = new DeleteIndexRequest("user");
        AcknowledgedResponse response = client.indices().delete(request, RequestOptions.DEFAULT);
        //删除索引的响应状态
        System.out.println("删除状态为:" + response.isAcknowledged());
        client.close();
    }
}

3、文档操作

创建数据模型

public class User {

    private String name;

    private Integer age;

    private String sex;

    public User() {
    }

    public User(String name, Integer age, String sex) {
        this.name = name;
        this.age = age;
        this.sex = sex;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    @Override
    public String toString() {
        return new StringJoiner(", ", User.class.getSimpleName() + "[", "]")
                .add("name='" + name + "'")
                .add("age=" + age)
                .add("sex='" + sex + "'")
                .toString();
    }
}

1、创建数据,添加到文档

public class ElasticsearchDocInsert {

    public static void main(String[] args) throws IOException {
        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(new HttpHost("localhost",9200)));

        IndexRequest indexRequest = new IndexRequest();
        indexRequest.index("user").id("1001");
        //创建数据对象
        User user = new User("xiaobear",18,"boy");
        //数据对象转为JSON
        ObjectMapper mapper = new ObjectMapper();
        String userJson = mapper.writeValueAsString(user);
        indexRequest.source(userJson, XContentType.JSON);
        //获取响应对象
        IndexResponse response = client.index(indexRequest, RequestOptions.DEFAULT);
        System.out.println("_index:" + response.getIndex());
        System.out.println("_id:" + response.getId());
        System.out.println("_result:" + response.getResult());
        client.close();
    }
}

输出结果

2、修改文档

public class ElasticsearchDocUpdate {

    public static void main(String[] args) throws IOException {
        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(new HttpHost("localhost",9200)));
        //修改文档
        UpdateRequest request = new UpdateRequest();
        request.index("user").id("1001");
        // 设置请求体,对数据进行修改
        request.doc(XContentType.JSON,"sex","girl");
        UpdateResponse response = client.update(request, RequestOptions.DEFAULT);
        System.out.println("_index:" + response.getIndex());
        System.out.println("_id:" + response.getId());
        System.out.println("_result:" + response.getResult());
        client.close();
    }
}

输出结果

3、查询文档

public class ElasticsearchDocGet {

    public static void main(String[] args) throws IOException {
        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(new HttpHost("localhost",9200)));
        //创建请求对象
        GetRequest request = new GetRequest().index("user").id("1001");
        //创建响应对象
        GetResponse response = client.get(request, RequestOptions.DEFAULT);
        // 打印结果信息
        System.out.println("_index:" + response.getIndex());
        System.out.println("_type:" + response.getType());
        System.out.println("_id:" + response.getId());
        System.out.println("source:" + response.getSourceAsString());
        client.close();
    }
}

输出结果

4、删除文档

public class ElasticsearchDoc_Delete {

    public static void main(String[] args) throws IOException {
        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(new HttpHost("localhost",9200)));
        //创建请求对象
        DeleteRequest request = new DeleteRequest().index("user").id("1");
        //创建响应对象
        DeleteResponse response = client.delete(request, RequestOptions.DEFAULT);
        //打印信息
        System.out.println(response.toString());
        client.close();
    }
}

输出结果

5、批量操作

1、批量新增

public class ElasticSearchBatchInsert {

    public static void main(String[] args) throws IOException {
        RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200)));
        //创建批量新增请求对象
        BulkRequest request = new BulkRequest();
        request.add(new IndexRequest().index("user").id("1004").source(XContentType.JSON,"name","xiaohuahua"));
        request.add(new IndexRequest().index("user").id("1005").source(XContentType.JSON,"name","zhangsan"));
        request.add(new IndexRequest().index("user").id("1006").source(XContentType.JSON,"name","lisi"));
        //创建响应对象
        BulkResponse response = client.bulk(request, RequestOptions.DEFAULT);
        System.out.println("took:" + response.getTook());
        System.out.println("items:" + response.getItems());
    }
}

输出结果

查询文档:

  • http://127.0.0.1:9200/user/_doc/1005

  • http://127.0.0.1:9200/user/_doc/1004

  • http://127.0.0.1:9200/user/_doc/1006

2、批量删除

public class ElasticSearchBatchDelete {

    public static void main(String[] args) throws IOException {
        RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200)));
        //创建批量新增请求对象
        BulkRequest request = new BulkRequest();
        request.add(new DeleteRequest().index("user").id("1001"));
        request.add(new DeleteRequest().index("user").id("1002"));
        request.add(new DeleteRequest().index("user").id("1003"));
        //创建响应对象
        BulkResponse response = client.bulk(request, RequestOptions.DEFAULT);
        System.out.println("took:" + response.getTook());
        Arrays.stream(response.getItems()).forEach(System.out::println);
        System.out.println("items:" + Arrays.toString(response.getItems()));
        System.out.println("status:" + response.status());
        System.out.println("失败消息:" + response.buildFailureMessage());
    }
}

输出结果

4、高级查询

1、请求体查询

1、查询所有索引数据

public class RequestBodyQuery {

    public static void main(String[] args) throws IOException {
        RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200)));
        //创建搜索对象
        SearchRequest request = new SearchRequest();
        request.indices("user");
        //构建查询的请求体
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        //查询所有对象
        sourceBuilder.query(QueryBuilders.matchAllQuery());
        request.source(sourceBuilder);

        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        //查询匹配
        SearchHits hits = response.getHits();
        System.out.println("took:" + response.getTook());
        System.out.println("是否超时:" + response.isTimedOut());
        System.out.println("TotalHits:" + hits.getTotalHits());
        System.out.println("MaxScore:" + hits.getMaxScore());
        for (SearchHit hit : hits) {
            System.out.println(hit.getSourceAsString());
        }
    }
}

输出结果

2、term查询

public class TremQuery {

    public static void main(String[] args) throws IOException {
        RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200)));
        //创建搜索对象
        SearchRequest request = new SearchRequest();
        request.indices("user");
        //构建查询的请求体
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        //查询所有对象
        sourceBuilder.query(QueryBuilders.termQuery("name","zhangsan"));
        request.source(sourceBuilder);

        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        //查询匹配
        SearchHits hits = response.getHits();
        System.out.println("took:" + response.getTook());
        System.out.println("是否超时:" + response.isTimedOut());
        System.out.println("TotalHits:" + hits.getTotalHits());
        System.out.println("MaxScore:" + hits.getMaxScore());
        for (SearchHit hit : hits) {
            System.out.println(hit.getSourceAsString());
        }
    }
}

输出结果

3、分页查询

public class PageQuery {

    public static void main(String[] args) throws IOException {
        RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200)));
        //创建搜索对象
        SearchRequest request = new SearchRequest();
        request.indices("user");
        //构建查询的请求体
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        //查询所有对象
        sourceBuilder.query(QueryBuilders.matchAllQuery());
        //分页查询 当前页其实索引 第一条数据的顺序号 from
        sourceBuilder.from(0);
        //每页显示多少条
        sourceBuilder.size(2);
        request.source(sourceBuilder);

        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        //查询匹配
        SearchHits hits = response.getHits();
        System.out.println("took:" + response.getTook());
        System.out.println("是否超时:" + response.isTimedOut());
        System.out.println("TotalHits:" + hits.getTotalHits());
        System.out.println("MaxScore:" + hits.getMaxScore());
        for (SearchHit hit : hits) {
            System.out.println(hit.getSourceAsString());
        }
    }
}

输出结果

4、数据排序

public class DataSorting {

    public static void main(String[] args) throws IOException {
        RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200)));
        //创建搜索对象
        SearchRequest request = new SearchRequest();
        request.indices("user");
        //构建查询的请求体
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        //查询所有对象
        sourceBuilder.query(QueryBuilders.matchAllQuery());
        //数据排序
        sourceBuilder.sort("age", SortOrder.DESC);

        request.source(sourceBuilder);
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        //查询匹配
        SearchHits hits = response.getHits();
        System.out.println("took:" + response.getTook());
        System.out.println("是否超时:" + response.isTimedOut());
        System.out.println("TotalHits:" + hits.getTotalHits());
        System.out.println("MaxScore:" + hits.getMaxScore());
        for (SearchHit hit : hits) {
            System.out.println(hit.getSourceAsString());
        }
    }
}

5、过滤字段

public class FilterFiled {

    public static void main(String[] args) throws IOException {
        RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200)));
        //创建搜索对象
        SearchRequest request = new SearchRequest();
        request.indices("user");
        //构建查询的请求体
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        //查询所有对象
        sourceBuilder.query(QueryBuilders.matchAllQuery());
        //数据排序
        sourceBuilder.sort("age", SortOrder.DESC);
        //查询过滤字段
        String[] excludes = {};
        //过滤掉name属性
        String[] includes = {"age"};
        sourceBuilder.fetchSource(includes,excludes);

        request.source(sourceBuilder);
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        //查询匹配
        SearchHits hits = response.getHits();
        System.out.println("took:" + response.getTook());
        System.out.println("是否超时:" + response.isTimedOut());
        System.out.println("TotalHits:" + hits.getTotalHits());
        System.out.println("MaxScore:" + hits.getMaxScore());
        for (SearchHit hit : hits) {
            System.out.println(hit.getSourceAsString());
        }
    }
}

输出结果

6、Bool查询

public class BoolSearch {

    public static void main(String[] args) throws IOException {
        RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200)));
        //创建搜索对象
        SearchRequest request = new SearchRequest();
        request.indices("user");
        //构建查询的请求体
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        //必须包含
        boolQuery.must(QueryBuilders.matchQuery("age",18));
        //一定不包含
        boolQuery.mustNot(QueryBuilders.matchQuery("name","lisi"));
        //可能包含
        boolQuery.should(QueryBuilders.matchQuery("name","zhangsan"));
        //查询所有对象
        sourceBuilder.query(boolQuery);
        
        request.source(sourceBuilder);
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        //查询匹配
        SearchHits hits = response.getHits();
        System.out.println("took:" + response.getTook());
        System.out.println("是否超时:" + response.isTimedOut());
        System.out.println("TotalHits:" + hits.getTotalHits());
        System.out.println("MaxScore:" + hits.getMaxScore());
        for (SearchHit hit : hits) {
            System.out.println(hit.getSourceAsString());
        }
    }
}

输出结果

7、范围查询

public class RangeSearch {

    public static void main(String[] args) throws IOException {
        RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200)));
        //创建搜索对象
        SearchRequest request = new SearchRequest();
        request.indices("user");
        //构建查询的请求体
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        //范围查询
        RangeQueryBuilder rangeQuery = QueryBuilders.rangeQuery("age");
        //大于等于
        rangeQuery.gte("19");
        //小于等于
        rangeQuery.lte("40");
        //查询所有对象
        sourceBuilder.query(rangeQuery);

        request.source(sourceBuilder);
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        //查询匹配
        SearchHits hits = response.getHits();
        System.out.println("took:" + response.getTook());
        System.out.println("是否超时:" + response.isTimedOut());
        System.out.println("TotalHits:" + hits.getTotalHits());
        System.out.println("MaxScore:" + hits.getMaxScore());
        for (SearchHit hit : hits) {
            System.out.println(hit.getSourceAsString());
        }
    }
}

输出结果

8、模糊查询

public class FuzzySearch {

    public static void main(String[] args) throws IOException {
        RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200)));
        //创建搜索对象
        SearchRequest request = new SearchRequest();
        request.indices("user");
        //构建查询的请求体
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        //模糊查询
        FuzzyQueryBuilder fuzzyQuery = QueryBuilders.fuzzyQuery("name", "zhangsan");
        fuzzyQuery.fuzziness(Fuzziness.ONE);

        sourceBuilder.query(fuzzyQuery);

        request.source(sourceBuilder);
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        //查询匹配
        SearchHits hits = response.getHits();
        System.out.println("took:" + response.getTook());
        System.out.println("是否超时:" + response.isTimedOut());
        System.out.println("TotalHits:" + hits.getTotalHits());
        System.out.println("MaxScore:" + hits.getMaxScore());
        for (SearchHit hit : hits) {
            System.out.println(hit.getSourceAsString());
        }
    }
}

输出结果

5、高亮查询

public class HighlightQuery {

    public static void main(String[] args) throws IOException {
        RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200)));
        //高亮查询
        SearchRequest request = new SearchRequest("user");
        //创建查询请求体构建器
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        //构建查询方式,高亮查询
        TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("name", "zhangsan");
        //设置查询方式
        sourceBuilder.query(termQueryBuilder);
        //构建高亮字段
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        //设置标签前缀
        highlightBuilder.preTags("<font color='red'");
        //设置标签后缀
        highlightBuilder.postTags("</font>");
        //设置高亮字段
        highlightBuilder.field("name");
        //设置高亮构建对象
        sourceBuilder.highlighter(highlightBuilder);
        //设置请求体
        request.source(sourceBuilder);
        //客户端发送请求,获取响应对象
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        // 打印响应结果
        SearchHits hits = response.getHits();
        System.out.println("took::"+response.getTook());
        System.out.println("time_out::"+response.isTimedOut());
        System.out.println("total::"+hits.getTotalHits());
        System.out.println("max_s core::"+hits.getMaxScore());
        System.out.println("hits::::>>");
        for (SearchHit hit : hits) {
            String sourceAsString = hit.getSourceAsString();
            System.out.println(sourceAsString);
            //打印高亮结果
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            System.out.println(highlightFields);
            System.out.println("<<::::");
        }
    }
}

输出结果

6、聚合查询

1、最大年龄

public class AggregateQuery {

    public static void main(String[] args) throws IOException {
        RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200)));
        SearchRequest request = new SearchRequest().indices("user");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.aggregation(AggregationBuilders.max("maxAge").field("age"));
        //设置请求体
        request.source(sourceBuilder);
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        //打印响应结果
        SearchHits hits = response.getHits();
        System.out.println("hits = " + hits);
        System.out.println(response);
    }
}

输出结果

2、分组查询

 public class GroupQuery {
 
     public static void main(String[] args) throws IOException {
         RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200)));
         //创建搜索对象
         SearchRequest request = new SearchRequest().indices("user");
         SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
         searchSourceBuilder.aggregation(AggregationBuilders.terms("age_groupby").field("age"));
 
         //设置请求体
         request.source(searchSourceBuilder);
         SearchResponse response = client.search(request, RequestOptions.DEFAULT);
         System.out.println(response.getHits());
         System.out.println(response);
 
     }
 }

输出结果

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Elasticsearch硬核入门教程(2022最全) 的相关文章

随机推荐

  • 数字表达_金字塔神秘数字之谜!142857这组神奇的数字表达着什么含义

    在埃及金字塔内 发现一组看似平凡 但很神奇的数字 142857 这组数字背后隐藏着人类无法解释的谜团 有人说这组数字和汶川大地震的时间偶合 这组数字隐藏了灾难发生的预言之秘 这到底是有心人无端的揣测 还是严谨的科学推论 142857这组数字
  • c++ list 容器splice函数

    list 的splice函数主要是用来合并两个list splice是list中特有的拼接方法 splice实现了不需要拷贝的list合并 即可以在常数时间内从list的一个区域拼接到另一个list的一个区域 也就是说splice是一个常数
  • ParallelLoopState.Break与ParallelLoopState.Stop区别

    ParallelLoopState Break与ParallelLoopState Stop区别 Break和Stop都是为了停止循环的一种手段 不同之处在于 Break不立马结束循环 而是要等所有小于ParallelLoopState L
  • shell脚本中调用java程序,并传递参数的方法

    为了方便运行多个java程序 选择写了脚本进行统一管理 简单介绍下传输参数的方法 假设要向file java传输参数 step1 需要先生成 class文件 javac Test java step2 在脚本中定义参数 int a 5 do
  • 拉格朗日插值多项式

    1 拉格朗日插值多项式 首先给出 n次插值基函数定义 若 n 次 多 项 式 l j
  • windows驱动开发8:虚拟摄像头方案

    一 摄像头框架 在业务场景中 有许多是需要应用能够通过摄像头的方式来访问相关的音视频数据 比如美颜 摄像头多路复用 IP摄像头接入视频会议等 这些功能通过虚拟摄像头的方式来实现 是一个比较通用的解决方案 那么如何及选用哪种技术方案来开发虚拟
  • SAR成像系列:【12】层析合成孔径雷达(层析SAR,Tomographic SAR,TomoSAR)

    自1995年Knaell为解决曲线SAR成像结果中的强旁瓣问题 将二维计算机断层 Computed Tomography 成像技术扩展到三维空间 并通过投影切片理论和后向投影算法获得了雷达成像三维空间的点响应函数 从而为分析三维成像分辨率和
  • __declspec(dllimport)的理解

    declspec dllimport MSDN中说明 不使用 declspec dllimport 也能正确编译代码 但使用 declspec dllimport 使编译器可以生成更好的代码 编译器之所以能够生成更好的代码 是因为它可以确定
  • windows 查看端口占用

    1 开始 运行 cmd 调出命令窗口 2 输入命令 netstat ano 列出所有端口的情况 在列表中我们观察被占用的端口 比如是49153 首先找到它 3 查看被占用端口对应的PID 输入命令 netstat aon findstr 4
  • 【云计算网络安全】解析DDoS攻击:工作原理、识别和防御策略

    文章目录 一 前言 二 什么是 DDoS 攻击 三 DDoS 攻击的工作原理 四 如何识别 DDoS 攻击 五 常见的 DDoS 攻击有哪几类 5 1 应用程序层攻击 5 1 1 攻击目标 5 1 2 应用程序层攻击示例 5 1 3 HTT
  • 打穿sqli-labs靶场第五天(less-7)文件写入

    打穿sqli labs靶场第五天 less 7 文件写入 环境配置 该关卡需要用到文件写入操作 所以需要开启MySQL中的文件写入 进入MySQL下的bin目录 用命令行连接数据库 查看是否开启文件写入 show variables lik
  • 代码规范化的七大原则

    代码规范化的七大原则 代码规范化基本上有七大原则 体现在空行 空格 成对书写 缩进 对齐 代码行 注释七方面的书写规范上 空行 定义变量后要空行 尽可能在定义变量的同时初始化该变量 即遵循就近原则 如果变量的引用和定义相隔比较远 那么变量的
  • 物体移动--通过改变transform--鼠标控制

    鼠标控制物体移动 1 物体移动到鼠标点击处 2 物体跟随鼠标移动 分为三步 获取鼠标位置 转化为世界坐标 物体移动 private Vector3 mopos private Vector3 gamepos void Start 物体的世界
  • 2022年计算机二级MS Office高级应用复习题及答案

    1 IP地址是一串难以记忆的数字 人们用域名来代替它 完成IP地址和域名之间转换工作的是 A 服务器 A DNS B URL C UNIX D ISDN 2 用高级程序设计语言编写的程序称为源程序 它 D A 只能在专门的机器上运行 B 无
  • 华为OD机试真题- 找出通过车辆最多颜色【2023Q1】【JAVA、Python、C++】

    题目描述 在一个狭小的路口 每秒只能通过一辆车 假如车辆的颜色只有3种 找出N秒内经过的最多颜色的车辆数量 三种颜色编号为0 1 2 输入描述 第一行输入的是通过的车辆颜色信息 0 1 1 2 代表4秒钟通过的车辆颜色分别是0 1 1 2
  • Java 基于协同过滤实现插画交流平台中的插画信息推荐功能

    Mahout 介绍 Mahout 是 Apache Software Foundation ASF 旗下的一个开源项目 提供一些可扩展的机器学习领域经典算法的实现 旨在帮助开发人员更加方便快捷地创建智能应用程序 Mahout包含许多实现 包
  • MyBatis增删改查(步骤详细,由浅入深,适合初学者,只看这一篇就够了)

    MyBatis目录 java 后端框架 MyBatis的使用 1 mybatis基本使用 2 mybatis工具类的封装和实现增删改查 3 mybatis中主要类的介绍 4 nybatis实现动态代理 使用的是反射机制 重点掌握 5 myb
  • [Pikachu靶场实战系列]RCE(远程系统命令执行)

    RCE介绍 exec ping 可以输入一个ip地址 结果发现页面无回显 难道不应该回显Ping命令的结果吗 不过我们不管他 继续下一步 在ip后用 分割再输入一个ls命令 发现ls命令被执行了 说明开发者没有做严格的安全控制 没有想到我们
  • python pandas 处理并excel 插入一列新的数据

    python pandas 处理excel并插入一列新的数据 接到个需求是在表格里塞入一列新的数据 假如分页的数据 页 条数 我们这是200条 页 用的是pandas import pandas as pd path excel room
  • Elasticsearch硬核入门教程(2022最全)

    Java全能学习 面试指南 https javaxiaobear cn 1 Elasticsearch概述 1 什么是Elasticsearch The Elastic Stack 包括 Elasticsearch Kibana Beats