准备项目

  • 创建 Maven 项目,在 IDEA 开发工具中创建 Maven 项目(模块), 取名叫 es。

  • 修改 pom 文件,增加 Maven 依赖关系

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    <dependencies>
    <dependency>
    <groupId>org.elasticsearch</groupId>
    <artifactId>elasticsearch</artifactId>
    <version>7.8.0</version>
    </dependency>
    <!-- elasticsearch 的客户端 -->
    <dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-high-level-client</artifactId>
    <version>7.8.0</version>
    </dependency>
    <!-- elasticsearch 依赖 2.x 的 log4j -->
    <dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
    <version>2.8.2</version>
    </dependency>
    <dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.8.2</version>
    </dependency>
    <dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.9</version>
    </dependency>
    <!-- junit 单元测试 -->
    <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    </dependency>
    </dependencies>

REST 客户端

  • ES 提供了两个 JAVA REST client 版本
    • Java Low Level REST Client: 低级别的 REST 客户端,通过 http 与集群交互,用户需自己编组请求 JSON 串,及解析响应 JSON 串。兼容所有 ES 版本
    • Java High Level REST Client: 高级别的 REST 客户端,基于低级别的 REST 客户端,增加了编组请求 JSON 串、解析响应 JSON 串等相关 api。使用的版本需要保持和 ES 服务端的版本一致,否则会有版本问题。

Low Level Client

High Level Client

  • 从 6.0.0 开始加入的,目的是以 java 面向对象的方式来进行请求、响应处理。

  • 每个 API 支持 同步/异步 两种方式,同步方法直接返回一个结果对象。异步的方法以 async 为后缀,通过 listener 参数来通知结果

  • API 及用法示例参考:https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high-supported-apis.html

  • 兼容性说明:

    • 依赖 java1.8 和 Elasticsearch core project
    • 请使用与服务端 ES 版本一致的客户端版本

使用

  • 创建 pers.fulsun.es.test._01_ESClient 类,代码中创建 Elasticsearch 客户端对象

  • 初始化:给定集群的多个节点地址,将客户端负载均衡地向这个节点地址集发请求:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public class _01_ESClient  {

    public static RestHighLevelClient getClient() {

    RestHighLevelClient client = new RestHighLevelClient(
    RestClient.builder(
    // 9200 端口为 Elasticsearch 默认的 Web 通信端口
    new HttpHost("localhost", 9200, "http"),
    new HttpHost("localhost", 9201, "http")
    )
    );
    return client;
    }
    }
  • Client 不再使用了,记得关闭它:

    1
    2
    3
    4
    5
    6
    public static void main(String[] args) throws IOException {
    RestHighLevelClient client = getClient();
    System.out.println(client);
    // 关闭客户端连接
    client.close();
    }

索引操作

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

创建索引

  • 代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    import java.io.IOException;
    import org.elasticsearch.client.RequestOptions;
    import org.elasticsearch.client.RestHighLevelClient;
    import org.elasticsearch.client.indices.CreateIndexRequest;
    import org.elasticsearch.client.indices.CreateIndexResponse;
    import pers.fulsun.es.test._01_ESClient;

    public class _01_ESTest_Index_Create {
    private static RestHighLevelClient client= _01_ESClient.getClient();;

    public static void main(String[] args) throws IOException {
    // 创建索引 - 请求对象
    CreateIndexRequest request = new CreateIndexRequest("user1");
    // 发送请求,获取响应
    CreateIndexResponse response = client.indices().create(request, RequestOptions.DEFAULT);
    boolean acknowledged = response.isAcknowledged();
    // 响应状态
    System.out.println("操作状态 = " + acknowledged);
    // 关闭客户端连接
    client.close();
    }
    }
  • 操作结果:

    1
    操作状态 = true

查找索引

  • 代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24

    import java.io.IOException;
    import org.elasticsearch.client.RequestOptions;
    import org.elasticsearch.client.RestHighLevelClient;
    import org.elasticsearch.client.indices.GetIndexRequest;
    import org.elasticsearch.client.indices.GetIndexResponse;
    import pers.fulsun.es.test._01_ESClient;

    public class _02_ESTest_Index_Search {
    private static RestHighLevelClient client = _01_ESClient.getClient();

    public static void main(String[] args) throws IOException {
    // 创建索引 - 请求对象
    GetIndexRequest request = new GetIndexRequest("user");
    // 发送请求,获取响应
    GetIndexResponse getIndexResponse = client.indices().get(request, RequestOptions.DEFAULT);
    // 响应状态
    System.out.println(getIndexResponse.getAliases());
    System.out.println(getIndexResponse.getMappings());
    System.out.println(getIndexResponse.getSettings());
    // 关闭客户端连接
    client.close();
    }
    }
  • 操作结果:

    1
    2
    3
    {user=[]}
    {user=org.elasticsearch.cluster.metadata.MappingMetadata@90ad7867}
    {user={"index.creation_date":"1637398010230","index.number_of_replicas":"1","index.number_of_shards":"1","index.provided_name":"user","index.uuid":"cG5E6L9jR8OwFiAXe0lNrw","index.version.created":"7080099"}}

删除索引

  • 代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public class _03_ESTest_Index_Delete {
    private static RestHighLevelClient client = _01_ESClient.getClient();

    public static void main(String[] args) throws IOException {
    // 删除索引 - 请求对象
    DeleteIndexRequest request = new DeleteIndexRequest("user");
    // 发送请求,获取响应
    AcknowledgedResponse response = client.indices().delete(request, RequestOptions.DEFAULT);
    // 响应状态
    System.out.println(response.isAcknowledged());
    // 关闭客户端连接
    client.close();
    }
    }
  • 操作结果:

    1
    true

文档操作

创建数据模型

  • 添加 lombok 依赖

    1
    2
    3
    4
    5
    <dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.20</version>
    </dependency>
  • 创建实体类

    1
    2
    3
    4
    5
    6
    @Data
    public class User {
    private String name;
    private String sex;
    private Integer age;
    }

新增文档

  • 代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    package pers.fulsun.es.test._03_doc;

    import com.fasterxml.jackson.databind.ObjectMapper;
    import java.io.IOException;
    import org.elasticsearch.action.index.IndexRequest;
    import org.elasticsearch.action.index.IndexResponse;
    import org.elasticsearch.client.RequestOptions;
    import org.elasticsearch.client.RestHighLevelClient;
    import org.elasticsearch.common.xcontent.XContentType;
    import pers.fulsun.es.test._01_ESClient;
    import pers.fulsun.es.test.entity.User;

    public class _01_ESTest_Doc_Insert {
    private static RestHighLevelClient client = _01_ESClient.getClient();

    public static void main(String[] args) throws IOException {
    // 新增文档 - 请求对象
    IndexRequest request = new IndexRequest();
    // 设置索引及唯一性标识
    request.index("user").id("1001");
    // 创建数据对象
    User user = new User();
    user.setName("zhangsan");
    user.setAge(30);
    user.setSex("男");
    ObjectMapper objectMapper = new ObjectMapper();
    String productJson = objectMapper.writeValueAsString(user);
    // 添加文档数据,数据格式为 JSON 格式
    request.source(productJson, XContentType.JSON);
    // 客户端发送请求,获取响应对象
    IndexResponse response = client.index(request, RequestOptions.DEFAULT);
    //// 3. 打印结果信息
    System.out.println("_index:" + response.getIndex());
    System.out.println("_id:" + response.getId());
    System.out.println("_result:" + response.getResult());
    // 关闭客户端连接
    client.close();
    }
    }
  • 操作结果:

    1
    2
    3
    _index:user
    _id:1001
    _result:CREATED

修改文档

  • 代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    package pers.fulsun.es.test._03_doc;

    import java.io.IOException;
    import org.elasticsearch.action.update.UpdateRequest;
    import org.elasticsearch.action.update.UpdateResponse;
    import org.elasticsearch.client.RequestOptions;
    import org.elasticsearch.client.RestHighLevelClient;
    import org.elasticsearch.common.xcontent.XContentType;
    import pers.fulsun.es.test._01_ESClient;

    public class _02_ESTest_Doc_Update {
    private static RestHighLevelClient client = _01_ESClient.getClient();

    public static void main(String[] args) throws IOException {
    // 修改文档 - 请求对象
    UpdateRequest request = new UpdateRequest();
    // 配置修改参数
    request.index("user").id("1001");
    // 设置请求体,对数据进行修改
    request.doc(XContentType.JSON, "sex", "女");
    // 添加文档数据,数据格式为 JSON 格式
    UpdateResponse response = client.update(request, RequestOptions.DEFAULT);
    // 客户端发送请求,获取响应对象
    //// 3. 打印结果信息
    System.out.println("_index:" + response.getIndex());
    System.out.println("_id:" + response.getId());
    System.out.println("_result:" + response.getResult());
    // 关闭客户端连接
    client.close();
    }
    }
  • 操作结果:

    1
    2
    3
    _index:user
    _id:1001
    _result:UPDATED

查询文档

  • 代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    public class _03_ESTest_Doc_Search {
    private static RestHighLevelClient client = _01_ESClient.getClient();

    public static void main(String[] args) throws IOException {
    GetRequest request = new GetRequest();
    request.index("user").id("1004");

    GetResponse response = client.get(request, RequestOptions.DEFAULT);
    System.out.println(response.isExists());
    System.out.println(response.getSourceAsString());

    // 关闭客户端连接
    client.close();
    }
    }
  • 操作结果:

    1
    2
    true
    {"name":"wangwu1","age":40,"sex":"女"}

删除文档

  • 代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    public class _04_ESTest_Doc_Delete {
    private static RestHighLevelClient client = _01_ESClient.getClient();

    public static void main(String[] args) throws IOException {

    DeleteRequest request = new DeleteRequest();
    request.index("user").id("1001");

    DeleteResponse response = client.delete(request, RequestOptions.DEFAULT);
    System.out.println(response.toString());

    // 关闭客户端连接
    client.close();
    }
    }
  • 操作结果:

    1
    DeleteResponse[index=user,type=_doc,id=1001,version=3,result=deleted,shards=ShardInfo{total=2, successful=1, failures=[]}]

批量插入

  • 代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    public class _05_ESTest_Doc_Insert_Batch {
    private static RestHighLevelClient client = _01_ESClient.getClient();

    public static void main(String[] args) throws IOException {

    // 批量插入数据
    BulkRequest request = new BulkRequest();
    request.add(new IndexRequest().index("user").id("1001").source(XContentType.JSON, "name", "zhangsan", "age",30,"sex","男"));
    request.add(new IndexRequest().index("user").id("1002").source(XContentType.JSON, "name", "lisi", "age",30,"sex","女"));
    request.add(new IndexRequest().index("user").id("1003").source(XContentType.JSON, "name", "wangwu", "age",40,"sex","男"));
    request.add(new IndexRequest().index("user").id("1004").source(XContentType.JSON, "name", "wangwu1", "age",40,"sex","女"));
    request.add(new IndexRequest().index("user").id("1005").source(XContentType.JSON, "name", "wangwu2", "age",50,"sex","男"));
    request.add(new IndexRequest().index("user").id("1006").source(XContentType.JSON, "name", "wangwu3", "age",50,"sex","男"));
    request.add(new IndexRequest().index("user").id("1007").source(XContentType.JSON, "name", "wangwu44", "age",60,"sex","男"));
    request.add(new IndexRequest().index("user").id("1008").source(XContentType.JSON, "name", "wangwu555", "age",60,"sex","男"));
    request.add(new IndexRequest().index("user").id("1009").source(XContentType.JSON, "name", "wangwu66666", "age",60,"sex","男"));

    BulkResponse response = client.bulk(request, RequestOptions.DEFAULT);
    System.out.println(response.getTook());
    System.out.println(response.getItems());
    // 关闭客户端连接
    client.close();
    }
    }
  • 操作结果:

    1
    2
    180ms
    [Lorg.elasticsearch.action.bulk.BulkItemResponse;@4b1d6571

批量删除

  • 代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    public class _06_ESTest_Doc_Delete_Batch {
    private static RestHighLevelClient client = _01_ESClient.getClient();

    public static void main(String[] args) throws IOException {
    // 批量删除数据
    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(response.getTook());
    System.out.println(response.getItems());

    // 关闭客户端连接
    client.close();
    }
    }
  • 操作结果:

    1
    2
    175ms
    [Lorg.elasticsearch.action.bulk.BulkItemResponse;@1a20270e

高级查询

查询所有索引数据

  • QueryBuilders.matchAllQuery())代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    package pers.fulsun.es.test._04_search;

    import java.io.IOException;
    import org.elasticsearch.action.search.SearchRequest;
    import org.elasticsearch.action.search.SearchResponse;
    import org.elasticsearch.client.RequestOptions;
    import org.elasticsearch.client.RestHighLevelClient;
    import org.elasticsearch.index.query.QueryBuilders;
    import org.elasticsearch.search.SearchHit;
    import org.elasticsearch.search.SearchHits;
    import org.elasticsearch.search.builder.SearchSourceBuilder;
    import pers.fulsun.es.test._01_ESClient;

    public class _01_ESTest_Doc_Search_All {
    private static RestHighLevelClient client = _01_ESClient.getClient();

    public static void main(String[] args) throws IOException {
    // 1. 查询索引的所有数据
    SearchRequest request = new SearchRequest();
    request.indices("user");

    // 构造查询条件
    SearchSourceBuilder builder = new SearchSourceBuilder();
    builder.query(QueryBuilders.matchAllQuery());

    // 添加查询条件到请求
    request.source(builder);
    // 发起查询
    SearchResponse response = client.search(request, RequestOptions.DEFAULT);

    // 查询匹配
    SearchHits hits = response.getHits();
    System.out.println("took:" + response.getTook());
    System.out.println("timeout:" + response.isTimedOut());
    System.out.println("total:" + hits.getTotalHits());
    System.out.println("MaxScore:" + hits.getMaxScore());
    System.out.println("hits========>>");
    for (SearchHit hit : hits) {
    // 输出每条查询的结果信息
    System.out.println(hit.getSourceAsString());
    }
    System.out.println("<<========");
    // 关闭客户端连接
    client.close();
    }
    }
  • 操作结果:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    took:1ms
    timeout:false
    total:6 hits
    MaxScore:1.0
    hits========>>
    {"name":"wangwu1","age":40,"sex":"女"}
    {"name":"wangwu2","age":50,"sex":"男"}
    {"name":"wangwu3","age":50,"sex":"男"}
    {"name":"wangwu44","age":60,"sex":"男"}
    {"name":"wangwu555","age":60,"sex":"男"}
    {"name":"wangwu66666","age":60,"sex":"男"}
    <<========

关键字查询

  • term 查询QueryBuilders.termQuery(...)),代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    public class _02_ESTest_Doc_Search_Term {
    private static RestHighLevelClient client = _01_ESClient.getClient();

    public static void main(String[] args) throws IOException {
    // 创建搜索请求对象
    SearchRequest request = new SearchRequest();
    request.indices("user");

    // 构建查询的请求体
    SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
    // text 类型的中文可以使用 keyword 避免分词
    sourceBuilder.query(QueryBuilders.termQuery("name.keyword", "wangwu3"));
    request.source(sourceBuilder);

    SearchResponse response = client.search(request, RequestOptions.DEFAULT);
    // 查询匹配
    SearchHits hits = response.getHits();
    System.out.println("took:" + response.getTook());
    System.out.println("timeout:" + response.isTimedOut());
    System.out.println("total:" + hits.getTotalHits());
    System.out.println("MaxScore:" + hits.getMaxScore());
    System.out.println("hits========>>");
    for (SearchHit hit : hits) {
    // 输出每条查询的结果信息
    System.out.println(hit.getSourceAsString());
    }
    System.out.println("<<========");
    // 关闭客户端连接
    client.close();
    }
    }
  • 操作结果:

    1
    2
    3
    4
    5
    6
    7
    took:3ms
    timeout:false
    total:1 hits
    MaxScore:1.89712
    hits========>>
    {"name":"wangwu3","age":50,"sex":"男"}
    <<========

分页查询

  • 代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    public class _03_ESTest_Doc_Search_Page {
    private static RestHighLevelClient client = _01_ESClient.getClient();

    public static void main(String[] args) throws IOException {
    // 创建搜索请求对象
    SearchRequest request = new SearchRequest();
    request.indices("user");

    // 构建查询的请求体
    SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
    sourceBuilder.query(QueryBuilders.matchAllQuery());

    // 分页查询
    // 当前页其实索引(第一条数据的顺序号为 0)
    sourceBuilder.from(0);
    // 每页显示多少条 size
    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("timeout:" + response.isTimedOut());
    System.out.println("total:" + hits.getTotalHits());
    System.out.println("MaxScore:" + hits.getMaxScore());
    System.out.println("hits========>>");
    for (SearchHit hit : hits) {
    // 输出每条查询的结果信息
    System.out.println(hit.getSourceAsString());
    }
    System.out.println("<<========");
    // 关闭客户端连接
    client.close();
    }
    }
  • 操作结果:

    1
    2
    3
    4
    5
    6
    7
    8
    took:1ms
    timeout:false
    total:6 hits
    MaxScore:1.0
    hits========>>
    {"name":"wangwu1","age":40,"sex":"女"}
    {"name":"wangwu2","age":50,"sex":"男"}
    <<========

数据排序

  • 代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    public class _04_ESTest_Doc_Search_Sort {
    private static RestHighLevelClient client = _01_ESClient.getClient();

    public static void main(String[] args) throws IOException {
    // 创建搜索请求对象
    SearchRequest request = new SearchRequest();
    request.indices("user");

    // 构建查询的请求体
    SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
    sourceBuilder.query(QueryBuilders.matchAllQuery());

    // 排序
    sourceBuilder.sort("age", SortOrder.ASC);

    request.source(sourceBuilder);

    SearchResponse response = client.search(request, RequestOptions.DEFAULT);
    // 查询匹配
    SearchHits hits = response.getHits();
    System.out.println("took:" + response.getTook());
    System.out.println("timeout:" + response.isTimedOut());
    System.out.println("total:" + hits.getTotalHits());
    System.out.println("MaxScore:" + hits.getMaxScore());
    System.out.println("hits========>>");
    for (SearchHit hit : hits) {
    // 输出每条查询的结果信息
    System.out.println(hit.getSourceAsString());
    }
    System.out.println("<<========");
    // 关闭客户端连接
    client.close();
    }
    }
  • 操作结果:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    took:25ms
    timeout:false
    total:6 hits
    MaxScore:NaN
    hits========>>
    {"name":"wangwu1","age":40,"sex":"女"}
    {"name":"wangwu2","age":50,"sex":"男"}
    {"name":"wangwu3","age":50,"sex":"男"}
    {"name":"wangwu44","age":60,"sex":"男"}
    {"name":"wangwu555","age":60,"sex":"男"}
    {"name":"wangwu66666","age":60,"sex":"男"}
    <<========

过滤字段

  • 代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    public class _05_ESTest_Doc_Search_Filter {
    private static RestHighLevelClient client = _01_ESClient.getClient();

    public static void main(String[] args) throws IOException {
    // 创建搜索请求对象
    SearchRequest request = new SearchRequest();
    request.indices("user");

    // 构建查询的请求体
    SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
    sourceBuilder.query(QueryBuilders.matchAllQuery());

    // 查询字段过滤
    String[] excludes = {"age"};
    String[] includes = {"name", "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("timeout:" + response.isTimedOut());
    System.out.println("total:" + hits.getTotalHits());
    System.out.println("MaxScore:" + hits.getMaxScore());
    System.out.println("hits========>>");
    for (SearchHit hit : hits) {
    // 输出每条查询的结果信息
    System.out.println(hit.getSourceAsString());
    }
    System.out.println("<<========");
    // 关闭客户端连接
    client.close();
    }
    }
  • 操作结果:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    took:1ms
    timeout:false
    total:6 hits
    MaxScore:1.0
    hits========>>
    {"name":"wangwu1"}
    {"name":"wangwu2"}
    {"name":"wangwu3"}
    {"name":"wangwu44"}
    {"name":"wangwu555"}
    {"name":"wangwu66666"}
    <<========

组合 (Bool) 查询

  • 代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    public class _06_ESTest_Doc_Search_Bool {
    private static RestHighLevelClient client = _01_ESClient.getClient();

    public static void main(String[] args) throws IOException {
    // 创建搜索请求对象
    SearchRequest request = new SearchRequest();
    request.indices("user");

    // 构建查询的请求体
    SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

    BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
    // 必须包含
    boolQueryBuilder.must(QueryBuilders.matchQuery("age", "60"));
    // 一定不含
    // boolQueryBuilder.mustNot(QueryBuilders.matchQuery("name", "wangwu66666"));
    // 可能包含
    boolQueryBuilder.should(QueryBuilders.termQuery("sex", "女"));
    boolQueryBuilder.should(QueryBuilders.termQuery("name.keyword", "wangwu44"));
    // 只有 must 和 should 会失效,满足任意一个 should 即可
    boolQueryBuilder.minimumShouldMatch(1);

    sourceBuilder.query(boolQueryBuilder);

    request.source(sourceBuilder);

    SearchResponse response = client.search(request, RequestOptions.DEFAULT);
    // 查询匹配
    SearchHits hits = response.getHits();
    System.out.println("took:" + response.getTook());
    System.out.println("timeout:" + response.isTimedOut());
    System.out.println("total:" + hits.getTotalHits());
    System.out.println("MaxScore:" + hits.getMaxScore());
    System.out.println("hits========>>");
    for (SearchHit hit : hits) {
    // 输出每条查询的结果信息
    System.out.println(hit.getSourceAsString());
    }
    System.out.println("<<========");
    // 关闭客户端连接
    client.close();
    }
    }
  • 操作结果:

    1
    2
    3
    4
    5
    6
    7
    8
    took:2ms
    timeout:false
    total:2 hits
    MaxScore:2.5404449
    hits========>>
    {"name":"wangwu44","age":60,"sex":"男"}
    {"name":"wangwu555","age":60,"sex":"女"}
    <<========

范围查询

  • 代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    public class _07_ESTest_Doc_Search_Range {
    private static RestHighLevelClient client = _01_ESClient.getClient();

    public static void main(String[] args) throws IOException {
    // 创建搜索请求对象
    SearchRequest request = new SearchRequest();
    request.indices("user");

    // 构建查询的请求体
    SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

    RangeQueryBuilder rangeQuery = QueryBuilders.rangeQuery("age");
    // 大于等于
    rangeQuery.gte("30");
    // 小于等于
    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("timeout:" + response.isTimedOut());
    System.out.println("total:" + hits.getTotalHits());
    System.out.println("MaxScore:" + hits.getMaxScore());
    System.out.println("hits========>>");
    for (SearchHit hit : hits) {
    // 输出每条查询的结果信息
    System.out.println(hit.getSourceAsString());
    }
    System.out.println("<<========");
    // 关闭客户端连接
    client.close();
    }
    }
  • 操作结果:

    1
    2
    3
    4
    5
    6
    7
    took:3ms
    timeout:false
    total:1 hits
    MaxScore:1.0
    hits========>>
    {"name":"wangwu1","age":40,"sex":"女"}
    <<========

模糊查询

  • 代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    public class _08_ESTest_Doc_Search_Fuzzy {
    private static RestHighLevelClient client = _01_ESClient.getClient();

    public static void main(String[] args) throws IOException {
    // 创建搜索请求对象
    SearchRequest request = new SearchRequest();
    request.indices("user");

    // 构建查询的请求体
    SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
    sourceBuilder.query(QueryBuilders.fuzzyQuery("name", "wangwu").fuzziness(Fuzziness.TWO));
    request.source(sourceBuilder);

    SearchResponse response = client.search(request, RequestOptions.DEFAULT);
    // 查询匹配
    SearchHits hits = response.getHits();
    System.out.println("took:" + response.getTook());
    System.out.println("timeout:" + response.isTimedOut());
    System.out.println("total:" + hits.getTotalHits());
    System.out.println("MaxScore:" + hits.getMaxScore());
    System.out.println("hits========>>");
    for (SearchHit hit : hits) {
    // 输出每条查询的结果信息
    System.out.println(hit.getSourceAsString());
    }
    System.out.println("<<========");
    // 关闭客户端连接
    client.close();
    }
    }
  • 操作结果:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    took:4ms
    timeout:false
    total:4 hits
    MaxScore:1.2837042
    hits========>>
    {"name":"wangwu1","age":40,"sex":"女"}
    {"name":"wangwu2","age":50,"sex":"男"}
    {"name":"wangwu3","age":50,"sex":"男"}
    {"name":"wangwu44","age":60,"sex":"男"}
    <<========

高亮查询

  • 代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    public class _09_ESTest_Doc_Search_HighLight {
    private static RestHighLevelClient client = _01_ESClient.getClient();

    public static void main(String[] args) throws IOException {
    // 创建搜索请求对象
    SearchRequest request = new SearchRequest();
    request.indices("user");

    // 构建查询的请求体
    SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

    // 构建查询方式
    TermsQueryBuilder termsQueryBuilder = QueryBuilders.termsQuery("name", "wangwu1");
    sourceBuilder.query(termsQueryBuilder);

    // 构建高亮字段
    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("timeout:" + response.isTimedOut());
    System.out.println("total:" + hits.getTotalHits());
    System.out.println("MaxScore:" + hits.getMaxScore());
    System.out.println("hits========>>");
    for (SearchHit hit : hits) {
    // 输出每条查询的结果信息
    System.out.println(hit.getSourceAsString());
    // 打印高亮结果
    Map<String, HighlightField> highlightFields = hit.getHighlightFields();
    System.out.println(highlightFields);
    }
    System.out.println("<<========");
    // 关闭客户端连接
    client.close();
    }
    }
  • 操作结果:

    1
    2
    3
    4
    5
    6
    7
    8
    took:3ms
    timeout:false
    total:1 hits
    MaxScore:1.0
    hits========>>
    {"name":"wangwu1","age":40,"sex":"女"}
    {name=[name], fragments[[<font color='red'>wangwu1</font>]]}
    <<========

聚合查询

  • 聚合操作分为指标聚合和分组聚合。RestHighLevelClient 可以使用 API 方法也可以使用 script 脚本进行聚合。

最大年龄

  • 代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    public class _010_ESTest_Doc_Search_Max {
    private static RestHighLevelClient client = _01_ESClient.getClient();

    public static void main(String[] args) throws IOException {
    // 构建查询的请求体
    SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
    // 构建聚合查询方式
    sourceBuilder.aggregation(AggregationBuilders.max("maxAge").field("age"));

    // 创建搜索请求对象
    SearchRequest request = new SearchRequest();
    request.indices("user");
    sourceBuilder.size(0);
    request.source(sourceBuilder);

    SearchResponse response = client.search(request, RequestOptions.DEFAULT);

    System.out.println("took:" + response.getTook());
    System.out.println("timeout:" + response.isTimedOut());
    System.out.println("aggregations========>>");
    // 和之前不同的是这里需要 getAggregations 获取聚合后的数据
    Aggregations aggregations = response.getAggregations();
    //从查询结果中获取刚才定义的最大值的名称
    Max maxAge = aggregations.get("maxAge");
    System.out.println(maxAge.getValue());
    System.out.println("<<========");
    // 关闭客户端连接
    client.close();
    }
    }
  • 操作结果:

    1
    2
    3
    4
    5
    took:2ms
    timeout:false
    aggregations========>>
    60.0
    <<========

stats 聚合

  • stats 聚合,对某个字段一次性返回 count,max,min,avg 和 sum 五个指标

  • 代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    import org.elasticsearch.search.aggregations.AggregationBuilders;
    import org.elasticsearch.search.aggregations.Aggregations;
    import org.elasticsearch.search.aggregations.metrics.Stats;
    public class _010_ESTest_Doc_Search_Stats {
    private static RestHighLevelClient client = _01_ESClient.getClient();

    public static void main(String[] args) throws IOException {
    // 构建查询的请求体
    SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
    // 构建聚合查询方式
    sourceBuilder.aggregation(AggregationBuilders.stats("stats_age").field("age"));

    // 创建搜索请求对象
    SearchRequest request = new SearchRequest();
    request.indices("user");
    sourceBuilder.size(0);
    request.source(sourceBuilder);

    SearchResponse response = client.search(request, RequestOptions.DEFAULT);

    System.out.println("took:" + response.getTook());
    System.out.println("timeout:" + response.isTimedOut());
    System.out.println("aggregations========>>");
    // 和之前不同的是这里需要 getAggregations 获取聚合后的数据
    Aggregations aggregations = response.getAggregations();
    //从查询结果中获取刚才定义的最大值的名称
    Stats stats = aggregations.get("stats_age");
    System.out.println("count:"+stats.getCount());
    System.out.println("min:"+stats.getMin());
    System.out.println("max:"+stats.getMax());
    System.out.println("avg:"+stats.getAvg());
    System.out.println("sum:"+stats.getSum());
    System.out.println("<<========");
    // 关闭客户端连接
    client.close();
    }
    }
  • 操作结果:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    took:1ms
    timeout:false
    aggregations========>>
    count:6
    min:40.0
    max:60.0
    avg:53.333333333333336
    sum:320.0
    <<========took:1ms
    timeout:false
    aggregations========>>
    count:6
    min:40.0
    max:60.0
    avg:53.333333333333336
    sum:320.0
    <<========

分组统计

  • 代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    public class _011_ESTest_Doc_Search_Group {
    private static RestHighLevelClient client = _01_ESClient.getClient();

    public static void main(String[] args) throws IOException {
    // 构建查询的请求体
    SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
    // 构建聚合查询方式
    TermsAggregationBuilder aggregationBuilder = AggregationBuilders
    .terms("age_tr").field("age"). //桶分组
    //求总数:可以从结果获取
    // subAggregation(AggregationBuilders.count("count_age").field("age")).
    subAggregation(AggregationBuilders.sum("sum_age").field("age")). //求和
    subAggregation(AggregationBuilders.avg("avg_age").field("age")); //求平均值
    sourceBuilder.aggregation(aggregationBuilder);

    // 创建搜索请求对象
    SearchRequest request = new SearchRequest();
    // 不输出原始数据
    sourceBuilder.size(0);
    // 打印 dsl 语句
    System.out.println(("dsl:" + sourceBuilder.toString()));
    // 设置索引以及填充语句
    request.indices("user");
    request.source(sourceBuilder);
    // 发送请求
    SearchResponse response = client.search(request, RequestOptions.DEFAULT);

    System.out.println("took:" + response.getTook());
    System.out.println("timeout:" + response.isTimedOut());
    System.out.println("aggregations========>>");
    // 和之前不同的是这里需要 getAggregations 获取聚合后的数据
    Aggregations aggregations = response.getAggregations();
    //ParsedTerms 有 long double String 三种类型
    ParsedLongTerms parsedStringTerms = aggregations.get("age_tr");
    List<? extends Bucket> buckets = parsedStringTerms.getBuckets();
    for (Terms.Bucket bucket : buckets) {
    //key 的数据
    String key = bucket.getKey().toString();
    // 分组的数据 = count
    long docCount = bucket.getDocCount();
    //获取数据
    Aggregations bucketAggregations = bucket.getAggregations();
    // long count = ((ParsedValueCount) bucketAggregations.get("count_age")).getValue();
    ParsedSum sum = bucketAggregations.get("sum_age");
    ParsedAvg avg = bucketAggregations.get("avg_age");
    System.out.println(
    key + ": count:"
    + docCount + ", sum:"
    + sum.getValue() + ", avg:"
    + avg.getValue());
    }

    // 关闭客户端连接
    client.close();
    }
    }
  • 操作结果:

    1
    2
    3
    4
    5
    6
    7
    dsl:{"size":0,"aggregations":{"age_tr":{"terms":{"field":"age","size":10,"min_doc_count":1,"shard_min_doc_count":0,"show_term_doc_count_error":false,"order":[{"_count":"desc"},{"_key":"asc"}]},"aggregations":{"sum_age":{"sum":{"field":"age"}},"avg_age":{"avg":{"field":"age"}}}}}}
    took:4ms
    timeout:false
    aggregations========>>
    60: count:3, sum:180.0, avg:60.0
    50: count:2, sum:100.0, avg:50.0
    40: count:1, sum:40.0, avg:40.0