Java 操作ElasticSearch API 大全,涵盖所有操作方式_elasticsearch-java security api create user

1.2.1 索引相关

TransportClient 索引相关API:https://www.elastic.co/guide/en/elasticsearch/client/java-api/7.6/java-admin-indices.html


要进行索引的管理必须获取到IndicesAdminClient对象来进行索引管理:

// 创建客户端管理对象
AdminClient adminClient = transportClient.admin();

IndicesAdminClient indices = adminClient.indices();

1)prepareXxx相关方法
  • 代码示例:
package com.es.demo;

import com.carrotsearch.hppc.cursors.ObjectObjectCursor;
import org.elasticsearch.action.admin.indices.get.GetIndexResponse;
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
import org.elasticsearch.action.admin.indices.settings.get.GetSettingsResponse;
import org.elasticsearch.client.AdminClient;
import org.elasticsearch.client.IndicesAdminClient;
import org.elasticsearch.client.Requests;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.net.InetAddress;
import java.util.Arrays;

/\*\*
 \* @author lscl
 \* @version 1.0
 \* @intro: Java操作ES TransportClient方式 索引管理
 \* 官网相关案例: https://www.elastic.co/guide/en/elasticsearch/client/java-api/7.6/java-admin-indices.html
 \*/
public class Demo02\_Index\_TransportClient\_Prepare {

    // 创建Client连接对象
    private Settings settings;

    // es客户端对象
    private TransportClient client;

    @Before
    public void before() throws Exception {

        // 创建Client连接对象
        settings = Settings.builder().put("cluster.name", "elasticsearch").build();

        // 客户端对象
        client = new PreBuiltTransportClient(settings)
                .addTransportAddress(new TransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
    }

    @After
    public void after() throws Exception {
        client.close();
    }

    // 创建索引
    @Test
    public void test1() throws Exception {

        // 创建客户端管理对象
        AdminClient adminClient = client.admin();

        // 获取索引操作对象
        IndicesAdminClient indices = adminClient.indices();

        // 创建索引
        indices.prepareCreate("goodsindex")
                .setSettings(
                        Settings.builder()
                                // primary shard
                                .put("index.number\_of\_shards", 3)
                                // replica shard
                                .put("index.number\_of\_replicas", 1)
                ).get();        // 执行创建

        // 快速创建索引
// client.admin().indices().prepareCreate("goodsindex").get();
    }

    // 创建映射
    @Test
    public void test2() throws Exception {
        /\*
 创建一个Content构建对象
 {
 "\_doc":{
 "properties": {
 "id":{
 "type":"integer",
 "store":"true"
 },
 "name":{
 "type":"text",
 "store":"true"
 },
 "title":{
 "type":"text",
 "store":"true"
 },
 "price":{
 "type":"double"
 },
 "category":{
 "fielddata": true,
 "type":"object"
 }
 }
 }
 }
 \*/
        XContentBuilder builder = XContentFactory.jsonBuilder()
                .startObject()
                .startObject("\_doc")
                .startObject("properties")
                .startObject("id")
                .field("type", "integer")
                .field("store", "true")
                .endObject()
                .startObject("name")
                .field("type", "text").field("store", "true").field("analyzer", "standard")
                .endObject()
                .startObject("title")
                .field("type", "text").field("store", "true").field("analyzer", "standard")
                .endObject()
                .startObject("price")
                .field("type", "double")
                .endObject()
                .startObject("category")
                .field("type", "text").field("fielddata", true)
                .endObject()
                .endObject()
                .endObject()
                .endObject();

        // 创建映射
        PutMappingRequest mapping = Requests.putMappingRequest("goodsindex")      // 该索引必须存在
                .type("\_doc").source(builder);

        // 索引操作对象
        IndicesAdminClient indices = client.admin().indices();

        // 添加映射
        indices.putMapping(mapping).get();

    }

    // 删除索引
    @Test
    public void test3() throws Exception {
        // 获取索引操作对象
        IndicesAdminClient indices = client.admin().indices();
        // 删除索引
        indices.prepareDelete("goodsindex").get();
    }


    // 更新索引
    @Test
    public void test4() throws Exception {
        // 获取索引操作对象
        IndicesAdminClient indices = client.admin().indices();

        // 执行更改
        indices.prepareUpdateSettings("goodsindex")
                .setSettings(
                        Settings.builder().put("index.number\_of\_replicas", 1)
                ).get();
    }

    // 查询索引信息
    @Test
    public void test5() throws Exception {
        // 获取索引操作对象
        IndicesAdminClient indices = client.admin().indices();

        // 制作查询
        GetIndexResponse indexResponse = indices.prepareGetIndex().get();

        // 获取索引名称
        String[] indexNames = indexResponse.getIndices();
        System.out.println("indexNames: " + Arrays.toString(indexNames));
    }


    // 查询索引配置
    @Test
    public void test6() throws Exception {
        // 获取索引操作对象
        IndicesAdminClient indices = client.admin().indices();

        // 执行查询
        GetSettingsResponse response = indices.prepareGetSettings("goodsindex").get();

        for (ObjectObjectCursor<String, Settings> cursor : response.getIndexToSettings()) {
            // 索引名称
            String index = cursor.key;

            // 索引配置信息
            Settings settings = cursor.value;

            // primary shard
            Integer shards = settings.getAsInt("index.number\_of\_shards", null);

            // replica shard
            Integer replicas = settings.getAsInt("index.number\_of\_replicas", null);

            System.out.println("index: " + index);
            System.out.println("settings: " + settings);
            System.out.println("shards: " + shards);
            System.out.println("replicas: " + replicas);
        }
    }
}

2)封装Request相关方法
  • 代码示例:
package com.es.demo;

import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.admin.indices.get.GetIndexRequest;
import org.elasticsearch.action.admin.indices.get.GetIndexResponse;
import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsRequest;
import org.elasticsearch.client.AdminClient;
import org.elasticsearch.client.IndicesAdminClient;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.net.InetAddress;
import java.util.HashMap;

/\*\*
 \* @author lscl
 \* @version 1.0
 \* @intro: Java操作ES TransportClient方式 索引管理
 \*/
public class Demo03\_Index\_TransportClient {

    // 创建Client连接对象
    private Settings settings;

    // es客户端对象
    private TransportClient client;

    @Before
    public void before() throws Exception {

        // 创建Client连接对象
        settings = Settings.builder().put("cluster.name", "elasticsearch").build();

        // 客户端对象
        client = new PreBuiltTransportClient(settings)
                .addTransportAddress(new TransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
    }

    @After
    public void after() throws Exception {
        client.close();
    }

    // 创建索引
    @Test
    public void test1() throws Exception {

        // 创建客户端管理对象
        AdminClient adminClient = client.admin();

        // 获取索引操作对象
        IndicesAdminClient indices = adminClient.indices();

        // 创建索引请求对象(具体用法: https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.6/java-rest-high-create-index.html)
        CreateIndexRequest createIndexRequest = new CreateIndexRequest("goodsindex");

        // 分片配置
        createIndexRequest.settings(
                Settings.builder()
                        .put("index.number\_of\_shards", 3)
                        .put("index.number\_of\_replicas", 2)
        );

// createIndexRequest.mapping() // 设置映射

        // 发送请求
        indices.create(createIndexRequest).get();
    }


    // 删除索引
    @Test
    public void test2() throws Exception {
        // 获取索引操作对象
        IndicesAdminClient indices = client.admin().indices();

        indices.delete(new DeleteIndexRequest("goodsindex")).get();
    }


    // 更新索引
    @Test
    public void test3() throws Exception {
        // 获取索引操作对象
        IndicesAdminClient indices = client.admin().indices();

        // 索引配置修改对象(具体用法: https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.6/java-rest-high-indices-put-settings.html)
        UpdateSettingsRequest updateSettingsRequest = new UpdateSettingsRequest();

        // 设置配置信息
        /\*updateSettingsRequest.settings(
 Settings.builder()
 .put("index.number\_of\_replicas", 1)
 .build()
 );\*/

        // 也可以使用Map
        HashMap<String, Object> settingsParams = new HashMap<>();
        settingsParams.put("index.number\_of\_replicas", 1);

        // 设置配置信息
        updateSettingsRequest.settings(settingsParams);

        indices.updateSettings(updateSettingsRequest).get();
    }

    // 查询索引
    @Test
    public void test4() throws Exception {
        // 获取索引操作对象
        IndicesAdminClient indices = client.admin().indices();

        // 索引查询对象
        GetIndexRequest getIndexRequest = new GetIndexRequest();

        // 执行查询,获取结果集
        GetIndexResponse indexResponse = indices.getIndex(getIndexRequest).get();

        // 获取索引名称
        String[] indexNames = indexResponse.getIndices();

        System.out.println("indexNames: " + indexNames);

// indexResponse.getAliases() // 获取别名
// indexResponse.getMappings() // 获取映射
// indexResponse.getSettings() // 获取配置信息
    }
}

1.2.2 文档相关

TransportClient文档管理相关API:https://www.elastic.co/guide/en/elasticsearch/client/java-api/7.6/index.html

在这里插入图片描述


同样,对于文档管理相关功能的API在ElasticSearch官网中提供有两种方式:

  • 1)prepareXxx相关方法
    • prepareIndex:创建文档
    • prepareDelete:删除文档
    • prepareUpdate:修改文档
    • prepareGet:查询文档
  • 2)直接功能方法:
    • index:创建文档
    • delete:删除文档
    • update:修改文档
    • get:查询文档
1)preapeXxx相关方法
  • 代码示例:
package com.es.demo;

import com.es.entity.Goods;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.net.InetAddress;
import java.util.Map;

/\*\*
 \* @author lscl
 \* @version 1.0
 \* @intro: Java操作ES TransportClient方式 文档管理
 \*/
public class Demo04\_Document\_TransportClient\_Prepare {
    // 创建Client连接对象
    private Settings settings;

    // es客户端对象
    private TransportClient client;

    @Before
    public void before() throws Exception {
        // 创建Client连接对象
        settings = Settings.builder().put("cluster.name", "elasticsearch").build();

        // 客户端对象
        client = new PreBuiltTransportClient(settings)
                .addTransportAddress(new TransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
    }

    @After
    public void after() throws Exception {
        client.close();
    }

    // 新增文档
    @Test
    public void test1() throws Exception {

        // 准备json数据
        Goods goods = new Goods("1",
                "xiaomi shouji",
                "xiaomi 5G paizhao shouji",
                2899.0D,
                new String[]{"5G", "paizhao"}
        );

        ObjectMapper objectMapper = new ObjectMapper();

        // 转换为JSON字符串
        String goodsJson = objectMapper.writeValueAsString(goods);

        // 执行请求
        client.prepareIndex("goodsindex", "\_doc", "1").setSource(goodsJson, XContentType.JSON).get();
    }

    // XContentBuilder方式构建文档
    @Test
    public void test2() throws Exception {
        //创建文档信息
        XContentBuilder builder = XContentFactory.jsonBuilder()
                .startObject()
                .field("id", "2")
                .field("name", "huawei shouji")
                .field("title", "huawei 4G youxi shouji")
                .field("price", 988)
                .field("category", new String[]{"4G", "youxi"})
                .endObject();

        // 建立文档对象
        client.prepareIndex("goodsindex", "\_doc", "2").setSource(builder).get();
    }

    // 删除文档
    @Test
    public void test3() throws Exception {
        client.prepareDelete("goodsindex", "\_doc", "1").get();
    }


    // 修改文档
    @Test
    public void test4() throws Exception {

        Goods goods = new Goods("2",
                "lianxian shouji",
                "lianxiang 5G youxi shouji",
                3899.0D,
                new String[]{"5G", "youxi"}
        );

        ObjectMapper om = new ObjectMapper();

        // 转换为JSON字符串
        String goodsJson = om.writeValueAsString(goods);

        // 执行请求
        client.prepareUpdate("goodsindex", "\_doc", "2").setDoc(goodsJson, XContentType.JSON).get();
    }

    // 查询文档
    @Test
    public void test5() throws Exception {

        // 执行查询
        GetResponse response = client.prepareGet("goodsindex", "\_doc", "1").get();

        // 查询结果以Map形式返回
        Map<String, Object> sourceAsMap = response.getSourceAsMap();
        System.out.println("map: " + sourceAsMap);

        // 查询结果以Json字符串形式返回
        String jsonStr = response.getSourceAsString();
        System.out.println("jsonStr: " + jsonStr);
    }
}

2)封装Request相关方法
  • 代码示例:
package com.es.demo;

import com.es.entity.Goods;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.net.InetAddress;
import java.util.Map;

/\*\*
 \* @author lscl
 \* @version 1.0
 \* @intro: Java操作ES TransportClient方式 文档管理
 \* 官网相关案例:
 \*/
public class Demo05\_Document\_TransportClient {
    // 创建Client连接对象
    private Settings settings;

    // es客户端对象
    private TransportClient client;

    @Before
    public void before() throws Exception {
        // 创建Client连接对象
        settings = Settings.builder().put("cluster.name", "elasticsearch").build();

        // 客户端对象
        client = new PreBuiltTransportClient(settings)
                .addTransportAddress(new TransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
    }

    @After
    public void after() throws Exception {
        client.close();
    }

    // 新增文档
    @Test
    public void test1() throws Exception {

        // 准备json数据
        Goods goods = new Goods("1",
                "xiaomi shouji",
                "xiaomi 5G paizhao shouji",
                2899.0D,
                new String[]{"5G", "paizhao"}
        );

        ObjectMapper objectMapper = new ObjectMapper();

        String goodsJson = objectMapper.writeValueAsString(goods);

        // 创建索引请求对象
        IndexRequest indexRequest = new IndexRequest("goodsindex", "\_doc", "1");

        // 传递json数据
        indexRequest.source(goodsJson, XContentType.JSON);

        // 执行请求
        client.index(indexRequest).get();
    }

    // 删除文档
    @Test
    public void test2() throws Exception {
        client.delete(new DeleteRequest("goodsindex", "\_doc", "1")).get();
    }


    // 修改文档
    @Test
    public void test3() throws Exception {

        // 准备Update请求
        UpdateRequest updateRequest = new UpdateRequest("goodsindex", "\_doc", "2");

        Goods goods = new Goods("1",
                "lianxian shouji",
                "lianxiang 5G youxi shouji",
                3899.0D,
                new String[]{"5G", "youxi"}
        );

        ObjectMapper om = new ObjectMapper();

        // 设置新文档
        updateRequest.doc(om.writeValueAsString(goods), XContentType.JSON);

        // 执行update请求
        client.update(updateRequest).get();
    }

    // 查询文档
    @Test
    public void test4() throws Exception {

        // 准备一个get请求
        GetRequest getRequest = new GetRequest("goodsindex", "\_doc", "2");
        // 执行get请求
        GetResponse res = client.get(getRequest).get();

        // 获取map数据
        Map<String, Object> goodsMap = res.getSource();
        System.out.println(goodsMap);

        // 获取json数据
        String goodsJson = res.getSourceAsString();
        System.out.println(goodsJson);
    }
}

1.2.3 搜索相关功能
  • 准备数据:
DELETE goodsindex

POST /goodsindex/_doc/1
{
  "name":"huawei shouji",
  "title":"huawei 4G quanmianping youxi shouji",
  "price":4899,
  "category":["youxi","4G","quanmianping"]
}

POST /goodsindex/_doc/2
{
  "name":"vivo shouji",
  "title":"vivo 5G paizhao shouji",
  "price":2899,
  "category":["5G","paizhao"]
}

POST /goodsindex/_doc/3
{
  "name":"oppo shouji",
  "title":"oppo 5G paizhao shouji",
  "price":1899,
  "category":["5G","paizhao"]
}

POST /goodsindex/_doc/4
{
  "name":"huawei shouji",
  "title":"huawei 5G youxi shouji",
  "price":3899,
  "category":["5G","youxi"]
}

POST /goodsindex/_doc/5
{
  "name":"xiaomi shouji",
  "title":"xiaomi 4G youxi shouji",
  "price":988,
  "category":["youxi","4G"]
}

POST /goodsindex/_doc/6
{
  "name":"xiaomi shouji",
  "title":"xiaomi 5G youxi qumianping shouji",
  "price":1899,
  "category":["youxi","5G","qumianping"]
}

POST /goodsindex/_doc/7
{
  "name":"xiaomi shouji",
  "title":"xiaomi 5G youxi shouji",
  "price":1299,
  "category":["youxi","5G"]
}

POST /goodsindex/_doc/8
{
  "name":"xiaomi shouji",
  "title":"xiaomi 4G shouji",
  "price":869,
  "category":["4G"]
}

POST /goodsindex/_doc/9
{
  "name":"huawei shouji",
  "title":"huawei 5G zhineng qumianping shouji",
  "price":2899,
  "category":["zhineng","5G","qumianping"]
}

POST /goodsindex/_doc/10
{
  "name":"youxi shouji",
  "title":"xiaomi 5G shouji",
  "price":2899,
  "category":["youxi","5G"]
}

1)SearchRequest搜索
  • SearchRequest:是ES提供的一个专门用于搜索的对象;在创建SearchRequest对象时指定要操作的索引(默认情况下在所有索引中搜索),SearchRequest可以执行封装大部分的搜索;例如string searchqueryDSLquery filterphrase searchterm queryquery stringhighlight search聚合搜索等;
  • SearchSourceBuilder:搜索源构建对象,在此对象中设置搜索的条件;最终将SearchSourceBuilder类设置到SearchRequest中,代表填充条件完毕;
  • QueryBuilders:查询条件构建对象,用于构建不同类型的查询;
QueryBuilders中的方法对应查询
matchQuery/matchAllQueryqueryDSL
boolQuery/must/mustNotquery filter
matchPhraseQueryphrase search
termQueryterm query
queryStringQueryquery string/string search

QueryBuilders更多用法:https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.6/java-rest-high-query-builders.html

  • 示例代码:
package com.es.demo;

import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.sort.SortOrder;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.net.InetAddress;

/\*\*
 \* @author lscl
 \* @version 1.0
 \* @intro: Java操作ES TransportClients的prepareSearch搜索
 \* 官网相关案例:
 \*/
public class Demo06\_Search\_TransportClient\_Prepare {
    // 创建Client连接对象
    private Settings settings;

    // es客户端对象
    private TransportClient client;

    @Before
    public void before() throws Exception {
        // 创建Client连接对象
        settings = Settings.builder().put("cluster.name", "elasticsearch").build();

        // 客户端对象
        client = new PreBuiltTransportClient(settings)
                .addTransportAddress(new TransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
    }

    @After
    public void after() throws Exception {
        client.close();
    }

    // 抽取打印方法
    public void print(SearchResponse res) {
        System.out.println("查询到: " + res.getHits().getTotalHits().value);

        SearchHits hits = res.getHits();
        for (SearchHit hit : hits) {
            System.out.println("score: " + hit.getScore());
            // 文档的json返回形式
            System.out.println(hit.getSourceAsString());
            System.out.println("------------");
        }
    }

    // DSL query 
    @Test
    public void queryDSL() throws Exception {

        // 创建搜索条件对象
        SearchResponse res = client.prepareSearch("goodsindex")
                .setTypes("\_doc")
                .setQuery(QueryBuilders.matchQuery("title", "xiaomi"))
                .get();

        print(res);
    }

    // query filter
    @Test
    public void queryFilter() throws Exception {

        SearchResponse res = client.prepareSearch("goodsindex")
                .setQuery(
                        QueryBuilders.boolQuery()
                                .must(QueryBuilders.matchQuery("title", "huawei"))
                                .mustNot(QueryBuilders.matchQuery("title", "youxi"))
                ).get();

        print(res);
    }

    // phrase search
    @Test
    public void phraseSearch() throws Exception {
        SearchResponse res = client.prepareSearch("goodsindex")
                .setQuery(QueryBuilders.matchPhraseQuery("title", "huawei 5G"))
                .get();

        print(res);
    }

    // term query
    @Test
    public void termQuery() throws Exception {

        SearchResponse res = client.prepareSearch("goodsindex")
                .setQuery(QueryBuilders.termQuery("title", "huawei 5G"))
                .get();

        print(res);
    }

    // string search
    @Test
    public void stringSearch() throws Exception {               // 带分词

        // 创建搜索条件对象
        SearchResponse res = client.prepareSearch("goodsindex")
                .setTypes("\_doc")
                .setQuery(QueryBuilders.queryStringQuery("title:4G"))
                .setQuery(QueryBuilders.queryStringQuery("category:youxi"))
                .setQuery(QueryBuilders.queryStringQuery("price:[2000 TO 5000]"))
                .addSort("price", SortOrder.DESC)
                .setFrom(0)
                .setSize(3)
                .get();

        print(res);
    }

    // query string
    @Test
    public void queryString() throws Exception {

        SearchResponse res = client.prepareSearch("goodsindex")
                .setQuery(
                        // AND/OR 运算符查询
// QueryBuilders.queryStringQuery("youxi 5G").field("name").field("title").defaultOperator(Operator.AND)

                        // 最少匹配词条
// QueryBuilders.queryStringQuery("huawei youxi 4G").field("title").minimumShouldMatch("2")

                        // 模糊查询
// QueryBuilders.queryStringQuery("huawkk~").field("title")

                        // 范围查询
                        QueryBuilders.queryStringQuery("[2000 TO 3000]").field("price")
                )
                .get();
        print(res);
    }

    // ids query
    @Test
    public void testIdQuery() throws Exception {

        SearchResponse res = client.prepareSearch("goodsindex")
                .setTypes("article")
                //设置要查询的id
                .setQuery(QueryBuilders.idsQuery().addIds("1", "2"))
                //执行查询
                .get();

        print(res);
    }
}

2)TransportClient搜索

使用TransportClient类提供的prepareSearch方法进行搜索,同样使用QueryBuilders进行搜索条件的构建,只是写法不同而已;

  • 代码示例:
package com.es.demo;

import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.net.InetAddress;

/\*\*
 \* @author lscl
 \* @version 1.0
 \* @intro: Java操作ES
 \* 官网相关案例:
 \*/
public class Demo07\_Search\_TransportClient {
    // 创建Client连接对象
    private Settings settings;

    // es客户端对象
    private TransportClient client;

    // 抽取打印方法
    public void print(SearchResponse res) {
        System.out.println("查询到: " + res.getHits().getTotalHits().value);

        SearchHits hits = res.getHits();
        for (SearchHit hit : hits) {
            System.out.println("score: " + hit.getScore());
            // 文档的json返回形式
            System.out.println(hit.getSourceAsString());
            System.out.println("------------");
        }
    }

    @Before
    public void before() throws Exception {
        // 创建Client连接对象
        settings = Settings.builder().put("cluster.name", "my-cluster").build();

        // 客户端对象
        client = new PreBuiltTransportClient(settings)
                .addTransportAddress(new TransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
        System.out.println(client.getClass());
    }

    @After
    public void after() throws Exception {
        client.close();
    }


    // query string
    @Test
    public void stringSearch() throws Exception {               // 带分词

        // 创建搜索对象
        SearchRequest searchRequest = new SearchRequest("goodsindex");

        // 创建查询构建对象
        SearchSourceBuilder builder = new SearchSourceBuilder();

        // 设置查询条件
        builder.query(QueryBuilders.queryStringQuery("title:shou\*"));
        builder.query(QueryBuilders.queryStringQuery("category:youxi"));
        builder.query(QueryBuilders.queryStringQuery("price:[2000 TO 5000]"));
        builder.sort("price", SortOrder.DESC);
        builder.from(0);
        builder.size(2);

        // 封装查询
        searchRequest.source(builder);

        // 执行查询获取结果集
        SearchResponse res = client.search(searchRequest).get();

        System.out.println("查询到: " + res.getHits().getTotalHits().value);

        SearchHits hits = res.getHits();
        for (SearchHit hit : hits) {
            System.out.println("score: " + hit.getScore());
            // 文档的json返回形式
            System.out.println(hit.getSourceAsString());
            System.out.println("------------");
        }

    }

    // DSL query
    @Test
    public void queryDSL() throws Exception {

        // 创建搜索请求对象
        SearchRequest searchRequest = new SearchRequest("goodsindex");

        // 创建查询构建对象
        SearchSourceBuilder builder = new SearchSourceBuilder();

        // 设置查询条件
// builder.query(QueryBuilders.matchAllQuery());
        builder.query(QueryBuilders.matchQuery("title", "xiaomi"));

        // 封装查询
        searchRequest.source(builder);

        // 执行查询获取结果集
        SearchResponse res = client.search(searchRequest).get();

        // 打印结果集
        print(res);
    }

    // query filter
    @Test
    public void queryFilter() throws Exception {
        SearchRequest searchRequest = new SearchRequest("goodsindex");

        // 创建查询构建对象
        SearchSourceBuilder builder = new SearchSourceBuilder();

        // 构建查询条件
        builder.query(
                QueryBuilders.boolQuery().
                        must(QueryBuilders.matchQuery("title", "huawei")).
                        mustNot(QueryBuilders.matchQuery("title", "youxi"))
        );

        // 封装查询条件
        searchRequest.source(builder);
        SearchResponse res = client.search(searchRequest).get();

        print(res);
    }

    // phrase query
    @Test
    public void phraseSearch() throws Exception {

        // 创建搜索请求对象
        SearchRequest searchRequest = new SearchRequest("goodsindex");

        // 创建查询构建对象
        SearchSourceBuilder builder = new SearchSourceBuilder();

        // 设置查询条件
        builder.query(QueryBuilders.matchPhraseQuery("title", "huawei 5G"));

        // 封装查询
        searchRequest.source(builder);

        // 执行查询获取结果集
        SearchResponse res = client.search(searchRequest).get();

        // 打印结果集
        print(res);
    }

    // term query
    @Test
    public void termQuery() throws Exception {

        // 创建搜索请求对象
        SearchRequest searchRequest = new SearchRequest("goodsindex");

        // 创建查询构建对象
        SearchSourceBuilder builder = new SearchSourceBuilder();

        // 设置查询条件
        builder.query(QueryBuilders.termQuery("title", "huawei 5G"));

        // 封装查询
        searchRequest.source(builder);

        // 执行查询获取结果集
        SearchResponse res = client.search(searchRequest).get();

        // 打印结果集
        print(res);
    }

    // query string
    @Test
    public void queryString() throws Exception {

        // 创建搜索请求对象
        SearchRequest searchRequest = new SearchRequest("goodsindex");

        // 创建查询构建对象
        SearchSourceBuilder builder = new SearchSourceBuilder();

        // 设置查询条件
        builder.query(
                // AND/OR 运算符查询
// QueryBuilders.queryStringQuery("youxi 5G").field("name").field("title").defaultOperator(Operator.AND)

                // 最少匹配词条
// QueryBuilders.queryStringQuery("huawei youxi 4G").field("title").minimumShouldMatch("2")

                // 模糊查询
// QueryBuilders.queryStringQuery("huawkk~").field("title")

                // 范围查询
                QueryBuilders.queryStringQuery("[2000 TO 3000]").field("price")
        );

        // 封装查询
        searchRequest.source(builder);

        // 执行查询获取结果集
        SearchResponse res = client.search(searchRequest).get();

        // 打印结果集
        print(res);
    }

}

1.2.4 高亮搜索

Java在实现ES的高亮搜索主要就在于一个类:HighlightBuilder。该类封装了高亮搜索的条件,如高亮字段/高亮前后缀等;

HighlightBuilder具体用法:https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.6/java-rest-high-search.html

package com.es.demo;

import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.net.InetAddress;
import java.util.Map;

/\*\*
 \* @author lscl
 \* @version 1.0
 \* @intro: 使用TransportClient进行高亮搜索
 \*/
public class Demo08\_Highlight\_Search\_TransportClient {
    // 创建Client连接对象
    private Settings settings;

    // es客户端对象
    private TransportClient client;

    // 抽取打印方法
    public void print(SearchResponse res) {
        System.out.println("查询到: " + res.getHits().getTotalHits().value);

        SearchHits hits = res.getHits();
        for (SearchHit hit : hits) {
            System.out.println("score: " + hit.getScore());
            // 文档的json返回形式
            System.out.println(hit.getSourceAsString());
            System.out.println("------------");
        }
    }

    @Before
    public void before() throws Exception {
        // 创建Client连接对象
        settings = Settings.builder().put("cluster.name", "elasticsearch").build();

        // 客户端对象
        client = new PreBuiltTransportClient(settings)
                .addTransportAddress(new TransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
    }

    @After
    public void after() throws Exception {
        client.close();
    }

    // 使用SearchRequest对象进行高亮搜索
    @Test
    public void searchQueryHighQuery() throws Exception {

        // 准备一个SearchRequest对象
        SearchRequest searchRequest = new SearchRequest("goodsindex");

        // 搜索条件构建对象
        SearchSourceBuilder builder = new SearchSourceBuilder();

        // 设置搜索条件
        builder.query(QueryBuilders.queryStringQuery("title:4G"));

        // 高亮构建对象
        HighlightBuilder highBuilder = new HighlightBuilder().field("title").preTags("<font color='red'>").postTags("</font>");

        // 设置高亮
        builder.highlighter(highBuilder);

        // 设置查询源
        searchRequest.source(builder);

        // 执行查询
        SearchResponse res = client.search(searchRequest).get();

        // 获取命中的记录
        SearchHits results = res.getHits();

        for (SearchHit result : results) {

            // 原始数据
            String sourceAsString = result.getSourceAsString();
            System.out.println(sourceAsString);

            // 高亮数据
            Map<String, HighlightField> high = result.getHighlightFields();
            System.out.println(high.get("title").fragments()[0].string());
            System.out.println("----------------");
        }
    }

    // 使用prepareSearch进行查询
    @Test
    public void transportClientHighQuery() throws Exception {

        // 高亮条件构造器
        HighlightBuilder highBuilder = new HighlightBuilder().field("title").preTags("</font style='red'>").postTags("</font>");

        // 创建搜索条件对象
        SearchResponse res = client.prepareSearch("goodsindex")
                .setTypes("\_doc")
                .setQuery(QueryBuilders.queryStringQuery("title:4G"))
                .highlighter(highBuilder)               // 设置高亮数据
                .get();

        // 获取命中的记录
        SearchHits results = res.getHits();

        for (SearchHit result : results) {

            // 原始数据
            String sourceAsString = result.getSourceAsString();
            System.out.println(sourceAsString);

            // 高亮数据
            Map<String, HighlightField> high = result.getHighlightFields();
            System.out.println(high.get("title").fragments()[0].string());
            System.out.println("----------------");
        }
    }
}

1.2.5 聚合搜索
  • 示例代码:
package com.es.demo;

import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.net.InetAddress;
import java.util.List;

/\*\*
 \* @author lscl
 \* @version 1.0
 \* @intro: 使用TransportClient进行聚合搜索
 \*/
public class Demo09\_Aggs\_TransportClient {

    // 创建Client连接对象
    private Settings settings;

    // es客户端对象
    private TransportClient client;

    // 抽取打印方法
    public void print(SearchResponse res) {
        System.out.println("查询到: " + res.getHits().getTotalHits().value);

        SearchHits hits = res.getHits();
        for (SearchHit hit : hits) {
            System.out.println("score: " + hit.getScore());
            // 文档的json返回形式
            System.out.println(hit.getSourceAsString());
            System.out.println("------------");
        }
    }

    @Before
    public void before() throws Exception {
        // 创建Client连接对象
        settings = Settings.builder().put("cluster.name", "my-cluster").build();

        // 客户端对象
        client = new PreBuiltTransportClient(settings)
                .addTransportAddress(new TransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
    }

    @After
    public void after() throws Exception {
        client.close();
    }

    // 计算每个分类下的商品数量(使用SearchRequest进行搜索)
    @Test
    public void aggs\_searchRequest() throws Exception {
        // 创建搜索对象
        SearchRequest searchRequest = new SearchRequest("goodsindex");

        // 条件构建对象
        SearchSourceBuilder searchBuilder =
                new SearchSourceBuilder().aggregation(AggregationBuilders.terms("group\_by\_category").field("category"));

        // 设置搜索条件
        searchRequest.source(searchBuilder);

        // 执行搜索
        SearchResponse res = client.search(searchRequest).get();

        // 获取聚合数据
        Aggregations aggregations = res.getAggregations();

        // 根据分组的名称获取对应的值
        Terms group_by_category = aggregations.get("group\_by\_category");

        // 获取
        List<? extends Terms.Bucket> buckets = group_by_category.getBuckets();
        for (Terms.Bucket bucket : buckets) {

            // key
            String key = bucket.getKeyAsString();
            System.out.println("key:" + key);

            // docCount
            long docCount = bucket.getDocCount();
            System.out.println("docCount:" + docCount);

            System.out.println("--------------------");
        }

    }

    // 计算每个分类下的商品数量(使用prepareSearch进行搜索)
    @Test
    public void aggs\_transportClientSearch() throws Exception {

        /\*
 GET goodsindex/\_doc/\_search
 {
 "size": 0,
 "aggs": {
 "group\_by\_category": {
 "terms": {
 "field": "category"
 }
 }
 }
 }
 \*/
        SearchResponse res = client.prepareSearch("goodsindex")
                .setQuery(QueryBuilders.matchAllQuery())
                .addAggregation(AggregationBuilders.terms("group\_by\_category").field("category"))
                .setSize(0)         // 不要原始数据(只要聚合数据)
                .get();

        // 获取聚合数据
        Aggregations aggregations = res.getAggregations();

        // 根据分组的名称获取对应的值
        Terms group_by_category = aggregations.get("group\_by\_category");

        // 获取
        List<? extends Terms.Bucket> buckets = group_by_category.getBuckets();
        for (Terms.Bucket bucket : buckets) {

            // key
            String key = bucket.getKeyAsString();
            System.out.println("key:" + key);

            // docCount
            long docCount = bucket.getDocCount();
            System.out.println("docCount:" + docCount);

            System.out.println("--------------------");
        }
    }

}

1.3 Low Level REST Client

Low Level REST Client:ElasticSearch官方的低级客户端。之所以称为低级客户端,是因为它几乎没有帮助 Java 用户构建请求或解析响应。它只处理请求的路径和查询字符串构造;请求响应后,只是将响应的数据直接响应给客户端,并没有做其他处理;

官方文档:https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.6/index.html

Low Level REST Client中相关的类:

  • RestClient:用于发送一次HTTP请求到ElasticSearch服务器
  • Request:用于封装一次HTTP请求,如请求方式/请求地址/请求体等
  • Response:RestClient执行完请求后得到的响应;

  • 示例代码:
package com.es.demo;

import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.StatusLine;
import org.apache.http.entity.ContentType;
import org.apache.http.nio.entity.NStringEntity;
import org.apache.http.util.EntityUtils;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.Request;
import org.elasticsearch.client.Response;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.util.Arrays;

/\*\*
 \* @author lscl
 \* @version 1.0
 \* @intro:
 \*/
public class Demo10\_RestClient {

    // 创建Client连接对象
    private RestClient restClient;

    // 抽取打印方法
    public void print(SearchResponse res) {
        System.out.println("查询到: " + res.getHits().getTotalHits().value);

        SearchHits hits = res.getHits();
        for (SearchHit hit : hits) {
            System.out.println("score: " + hit.getScore());
            // 文档的json返回形式
            System.out.println(hit.getSourceAsString());
            System.out.println("------------");
        }
    }

    @Before
    public void before() throws Exception {
        // 创建Client连接对象
        restClient = RestClient.builder(
                new HttpHost("localhost", 9200, "http")
        ).build();

    }

    @After
    public void after() throws Exception {
        restClient.close();
    }

    // 发送GET请求
    @Test
    public void test1() throws Exception {
        Request request = new Request(
                "GET",
                "/");

        Response response = restClient.performRequest(request);

        // 响应体
        HttpEntity entity = response.getEntity();
        System.out.println("entity: " + entity);
        System.out.println(EntityUtils.toString(entity));
        System.out.println("-----------------");

        // 响应头
        Header[] headers = response.getHeaders();
        System.out.println("headers: " + Arrays.toString(headers));
        System.out.println("-----------------");

        // 响应行
        StatusLine statusLine = response.getStatusLine();
        System.out.println("statusLine: " + statusLine);
        System.out.println("-----------------");

    }

    // get请求
    @Test
    public void test2() throws Exception {
        Request request = new Request(
                "GET",
                "/goodsindex/\_doc/\_search");

        Response response = restClient.performRequest(request);

        // 响应体
        HttpEntity entity = response.getEntity();
        System.out.println(EntityUtils.toString(entity));       // 将响应体以Json方式响应
    }

    // get请求
    @Test
    public void test3() throws Exception {

        /\*
 GET goodsindex/\_doc/\_search
 {
 "query": {
 "match": {
 "title": "5g"
 }
 }
 }
 \*/
        Request request = new Request(
                "GET",
                "/goodsindex/\_doc/\_search");

        // 准备Json请求体字符串
        String requestEntityJson = "{\n" +
                " \"query\": {\n" +
                " \"match\": {\n" +
                " \"title\": \"5g\"\n" +
                " }\n" +
                " }\n" +
                " }";

        // 封装成HttpEntity请求体对象
        HttpEntity httpEntity = new NStringEntity(requestEntityJson, ContentType.APPLICATION_JSON);

        // 将请求体设置到本次请求上
        request.setEntity(httpEntity);

        // 执行请求获取结果集
        Response response = restClient.performRequest(request);

        // 响应体
        HttpEntity responseEntity = response.getEntity();
        System.out.println(EntityUtils.toString(responseEntity));       // 将响应体以Json方式响应
    }

    // get请求
    @Test
    public void test4() throws Exception {

        /\*
 GET goodsindex/\_doc/\_search
 {
 "query": {
 "match": {
 "title": "shouji"
 }
 },
 "sort": [
 {
 "price": {
 "order": "desc"
 }
 }
 ]
 }
 \*/
        Request request = new Request(
                "GET",
                "/goodsindex/\_doc/\_search");

        // 准备Json请求体字符串
        String requestEntityJson = "{\n" +
                " \"query\": {\n" +
                " \"match\": {\n" +
                " \"title\": \"shouji\"\n" +
                " }\n" +
                " },\n" +
                " \"sort\": [\n" +
                " {\n" +
                " \"price\": {\n" +
                " \"order\": \"desc\"\n" +
                " }\n" +
                " }\n" +
                " ]\n" +
                " }";


        // 将请求体设置到本次请求上
        request.setJsonEntity(requestEntityJson);

        // 执行请求获取结果集
        Response response = restClient.performRequest(request);

        // 响应体
        HttpEntity responseEntity = response.getEntity();
        System.out.println(EntityUtils.toString(responseEntity));       // 将响应体以Json方式响应
    }

    // post请求
    @Test
    public void test5() throws Exception {

        /\*
 POST /goodsindex/\_doc/100
 {
 "name":"meizu shouji",
 "title":"meizu 4G gaoqing youxi shouji",
 "price":1899,
 "category":["youxi","4G","gaoqing"]
 }
 \*/
        Request request = new Request(
                "POST",
                "/goodsindex/\_doc/100");

        // 准备Json请求体字符串
        String requestEntityJson = "{\n" +
                " \"name\":\"meizu shouji\",\n" +
                " \"title\":\"meizu 4G gaoqing youxi shouji\",\n" +
                " \"price\":1899,\n" +
                " \"category\":[\"youxi\",\"4G\",\"gaoqing\"]\n" +
                " }";


        // 将请求体设置到本次请求上
        request.setJsonEntity(requestEntityJson);

        // 格式化响应结果集
        request.addParameter("pretty", "true");

        // 执行请求获取结果集
        Response response = restClient.performRequest(request);

        // 响应体
        HttpEntity responseEntity = response.getEntity();
        System.out.println(EntityUtils.toString(responseEntity));       // 将响应体以Json方式响应
    }

    // put请求
    @Test
    public void test6() throws Exception {

        /\*
 PUT /goodsindex/\_doc/100
 {
 "name":"meizu shouji",
 "title":"meizu 5G paizhao shouji",
 "price":2899,
 "category":["paizhao","5G","gaoqing"]
 }
 \*/
        Request request = new Request(
                "PUT",
                "/goodsindex/\_doc/100");

        // 准备Json请求体字符串
        String requestEntityJson = "{\n" +
                " \"name\":\"meizu shouji\",\n" +
                " \"title\":\"meizu 5G paizhao shouji\",\n" +
                " \"price\":2899,\n" +
                " \"category\":[\"paizhao\",\"5G\",\"gaoqing\"]\n" +
                " }";


        // 将请求体设置到本次请求上
        request.setJsonEntity(requestEntityJson);

        // 格式化响应结果集
        request.addParameter("pretty", "true");

        // 执行请求获取结果集
        Response response = restClient.performRequest(request);

        // 响应体
        HttpEntity responseEntity = response.getEntity();
        System.out.println(EntityUtils.toString(responseEntity));       // 将响应体以Json方式响应
    }


    // delete请求
    @Test
    public void test7() throws Exception {

        /\*
 DELETE /goodsindex/\_doc/100
 \*/
        Request request = new Request(
                "DELETE",
                "/goodsindex/\_doc/100");

        // 格式化响应结果集
        request.addParameter("pretty", "true");

        // 执行请求获取结果集
        Response response = restClient.performRequest(request);

        // 响应体
        HttpEntity responseEntity = response.getEntity();
        System.out.println(EntityUtils.toString(responseEntity));       // 将响应体以Json方式响应
    }

}


1.4 High Level REST Client

Java 高级 REST 客户端在 Java 低级 REST 客户端之上运行。它的主要目标是公开 API 特定的方法,接受请求对象作为参数并返回响应对象,以便请求编组和响应解组由客户端本身处理。要求Elasticsearch版本为2.0或者更高。

官方文档:https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.6/index.html

  • High Level REST Client中相关的类:High Level REST Client和TransportClient一样支持IndexRequestDeleteRequestUpdateRequestGetRequestSearchRequest,因此用法和我们之前使用TransportClient类似;

  • 示例代码:
package com.es.demo;

import com.es.entity.Goods;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.http.HttpHost;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

/\*\*
 \* @author lscl
 \* @version 1.0
 \* @intro: RestHighLevelClient 用法
 \*/
public class Demo11\_RestHighLevelClient {
    // 高级查询对象
    private RestHighLevelClient client;

    // 抽取打印方法
    public void print(SearchResponse res) {
        System.out.println("查询到: " + res.getHits().getTotalHits().value);

        SearchHits hits = res.getHits();
        for (SearchHit hit : hits) {
            System.out.println("score: " + hit.getScore());
            // 文档的json返回形式
            System.out.println(hit.getSourceAsString());
            System.out.println("------------");
        }
    }

    @Before
    public void before() throws Exception {
        //获取连接客户端
        client = new RestHighLevelClient(
                RestClient.builder(
                        new HttpHost("localhost", 9200, "http")
                )
        );
    }

    @After
    public void after() throws Exception {
        client.close();
    }

    @Test
    public void insert() throws Exception {         // 增
        // 准备数据
        Goods goods = new Goods("11",
                "meizu shouji", "meizu 5G zhineng paizhao shouji",
                2899.0D, new String[]{"5G", "zhineng", "paizhao"}
        );

        // 转换为json
        String goodsJson = new ObjectMapper().writeValueAsString(goods);

        // 准备索引请求对象
        IndexRequest indexRequest = new IndexRequest("goodsindex", "\_doc", "11");

        // 设置数据源
        indexRequest.source(goodsJson, XContentType.JSON);

        client.index(indexRequest, RequestOptions.DEFAULT);
    }


    @Test
    public void delete() throws Exception {         // 删

        DeleteRequest deleteRequest = new DeleteRequest("goodsindex", "\_doc", "1");

        client.delete(deleteRequest, RequestOptions.DEFAULT);
    }


    @Test
    public void update() throws Exception {         // 改

        UpdateRequest updateRequest = new UpdateRequest("goodsindex", "\_doc", "2");

        // 准备数据
        Goods goods = new Goods("2",
                "zhongxing shouji", "zhongxing 4G youxi shouji",
                2899.0D, new String[]{"4G", "youxi"});

        String goodsJson = new ObjectMapper().writeValueAsString(goods);

        updateRequest.doc(goodsJson, XContentType.JSON);

        client.update(updateRequest, RequestOptions.DEFAULT);
    }


    @Test
    public void query() throws Exception {          // 查

        GetRequest getRequest = new GetRequest("goodsindex", "\_doc", "2");

        GetResponse res = client.get(getRequest, RequestOptions.DEFAULT);

        System.out.println(res.getSourceAsString());
    }

    @Test
    public void searchRequest() throws Exception {      // searchRequest查询

        SearchRequest searchRequest = new SearchRequest("goodsindex");

        SearchSourceBuilder builder = new SearchSourceBuilder()
                .query(QueryBuilders.queryStringQuery("title:meizu"));

        searchRequest.source(builder);

        SearchResponse res = client.search(searchRequest, RequestOptions.DEFAULT);

        print(res);
    }
}

1.5 SQL搜索ElasticSearch

1)开启ES白金版功能
  • 1)

在这里插入图片描述

  • 2)

在这里插入图片描述

  • 3):

在这里插入图片描述

  • 4):

在这里插入图片描述

2)示例代码
  • 引入相关依赖:
<!--配置ES的SQL支持 maven仓库-->
<repositories>
    <repository>
        <id>elastic.co</id>
        <url>https://artifacts.elastic.co/maven</url>
    </repository>
</repositories>

<dependencies>
    <dependency>
        <groupId>org.elasticsearch.plugin</groupId>
        <artifactId>x-pack-sql-jdbc</artifactId>
        <version>7.6.2</version>
    </dependency>
</dependencies>

  • 示例代码:
package com.es.demo;

import org.junit.Test;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

/\*\*
 \* @author lscl
 \* @version 1.0
 \* @intro:
 \*/
public class Demo12\_ES\_JDBC {

    @Test
    public void test1() throws Exception {
        // 获取与ES服务器的连接
        Connection connection = DriverManager.getConnection("jdbc:es://http://localhost:9200");

        // 创建语句对象
        Statement statement = connection.createStatement();

        // 执行SQL,获取结果集
        ResultSet rs = statement.executeQuery("select \* from goodsindex");

        while (rs.next()) {
            System.out.print("name: " + rs.getString("name")+"\t");
            System.out.print("title: " + rs.getString("title")+"\t");
            System.out.print("price: " + rs.getString("price")+"\t");
            System.out.print("category: " + rs.getString("category")+"\t");
            System.out.println();
        }

        connection.close();
    }
}

二、Spring Data ElasticSearch

Spring Data ElasticSearchSpringData大家族的一员,Spring Data 的使命是给各种数据访问提供统一的编程接口,不管是关系型数据库(如MySQL),还是非关系数据库(如Redis),或者类似Elasticsearch这样的索引数据库。从而简化开发人员的代码,提高开发效率。

在这里插入图片描述

  • 引入项目依赖:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.es</groupId>
    <artifactId>02_ElasticSearch_Template</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.1.RELEASE</version>
        <relativePath/>
    </parent>

    <!--锁定ES版本-->
    <properties>
        <elasticsearch.version>7.6.2</elasticsearch.version>
    </properties>

    <dependencies>
        <!--SpringBoot整合Elasticsearch-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
        </dependency>
        
        <!--SpringBoot整合测试单元-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
        
        <!--lombok插件-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.12</version>
        </dependency>

    </dependencies>
</project>

2.1 Template 查询

SpringData家族为大部分产品都提供了查询模板类,例如JdbcTemplate、RedisTemplate、RabbitTempalte等简化我们的操作;同样,SpringDataElasticSearch提供了ElasticsearchRestTemplate类来简化Java操作ES的代码;

  • 在SpringDataElasticSearch官网中提供有四种操作ES的相关类:
    • IndexOperations:有关于索引相关操作,如创建或删除索引。
    • DocumentOperations:有关于文档的操作,根据文档的id进行存储、更新和检索文档的操作。
    • SearchOperations:搜索文档相关操作
    • ElasticsearchOperations :结合了DocumentOperations和SearchOperations接口。

在这里插入图片描述

Spring官网中提供有ElasticsearchTemplateElasticsearchRestTemplate 两个ES相关模板类,其中ElasticsearchTemplate是使用TransportClient对ElasticsearchOperations的实现;ElasticsearchRestTemplate 则是使用High Level REST ClientElasticsearchOperations的实现;

Tips:ElasticsearchTemplate从4.0版本起不再使用,使用ElasticsearchRestTemplate代替。


  • 定义实体类:

关于实体类定义的详细文档:https://docs.spring.io/spring-data/elasticsearch/docs/4.0.3.RELEASE/reference/html/#elasticsearch.mapping

package com.es.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;

@Data
@AllArgsConstructor
@NoArgsConstructor
@Document(indexName = "goodsindex", type = "\_doc", shards = 1, replicas = 2)
// ES7.0后不支持type功能(一个索引只能有一个type,名为\_doc)
public class Goods {

    @Id
    private String id;

    @Field(index = true, store = false, fielddata = false, type = FieldType.Text, analyzer = "standard", searchAnalyzer = "standard")
    private String name;

    @Field(analyzer = "standard", searchAnalyzer = "standard")
    private String title;

    @Field
    private Double price;

    @Field
    private String[] category;
}

  • XxxOperations示例代码:
import com.es.Application;
import com.es.entity.Goods;
import org.elasticsearch.index.query.QueryBuilders;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.elasticsearch.core.\*;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.test.context.junit4.SpringRunner;

@SpringBootTest(classes = Application.class)
@RunWith(SpringRunner.class)
public class Demo01\_Options {

    @Autowired
    private DocumentOperations documentOperations;

    @Autowired
    private SearchOperations searchOperations;

    @Autowired
    private ElasticsearchOperations elasticsearchOperations;

    @Autowired
    private ElasticsearchRestTemplate elasticsearchRestTemplate;

    @Test
    public void test1() {

        // 获取IndexOperations索引操作对象
        IndexOperations indexOperations = elasticsearchOperations.indexOps(Goods.class);

        // 创建索引
        indexOperations.create();
    }

    @Test
    public void test2() {
        Goods goods = new Goods(
                "1",
                "xiaomi shouji",
                "xiaomi 5g youxi shouji",
                2000.0D,
                new String[]{"5g", "youxi"}
        );

        documentOperations.save(goods);
    }

    @Test
    public void test3() {
        // 本地查询
        NativeSearchQuery query = new NativeSearchQuery(QueryBuilders.matchAllQuery());

        SearchHits<Goods> searchHits = searchOperations.search(query, Goods.class);
        for (SearchHit<Goods> searchHit : searchHits) {
            Goods goods = searchHit.getContent();
            System.out.println(goods);
        }
    }

    @Test
    public void test4() {
        Goods goods = elasticsearchOperations.get("1", Goods.class);
        System.out.println(goods);
    }

}

  • ElasticsearchRestTemplate 示例代码:
import com.es.Application;
import com.es.entity.Goods;
import org.elasticsearch.index.query.QueryBuilders;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.document.Document;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.UpdateQuery;
import org.springframework.test.context.junit4.SpringRunner;

@SpringBootTest(classes = Application.class)
@RunWith(SpringRunner.class)
public class Demo02\_Template {

    @Autowired
    private ElasticsearchRestTemplate restTemplate;

    @Test
    public void insert() {           // insert
        Goods goods = new Goods(
                "1",
                "huawei shouji",
                "huawei 5G youxi shouji",
                1889.0D,
                new String[]{"youxi", "5G"}
        );

        restTemplate.save(goods, IndexCoordinates.of("goodsindex"));
    }


    @Test
    public void delete() {           // delete
        restTemplate.delete("2", IndexCoordinates.of("goodsindex"));
    }

    @Test
    public void update() {

        Document goodsDoc = Document.create();
        goodsDoc.append("id", "1");
        goodsDoc.append("name", "meizu shouji");
        goodsDoc.append("title", "meizu 4G paizhao shouji");
        goodsDoc.append("double", 1889.0D);
        goodsDoc.append("category", new String[]{"paizhao", "4G"});

        UpdateQuery updateQuery = UpdateQuery.builder("1")
                .withDocument(goodsDoc)
                .build();

        restTemplate.update(updateQuery, IndexCoordinates.of("goodsindex"));
    }

    @Test
    public void query() {           // query
        Goods goods = restTemplate.get("1", Goods.class, IndexCoordinates.of("goodsindex"));
        System.out.println(goods);
    }


    @Test
    public void queryForNative() {          // 使用本地查询

        // 使用本地搜索查询(原生ES的API查询)
        NativeSearchQuery query = new NativeSearchQueryBuilder()
                .withQuery(QueryBuilders.matchAllQuery())
                .build();

        SearchHits<Goods> goodsSearchHits = restTemplate.search(query, Goods.class, IndexCoordinates.of("goodsindex"));
        for (SearchHit<Goods> goodsHit : goodsSearchHits) {
            Goods goods = goodsHit.getContent();
            System.out.println(goods);
        }
    }

}

2.2 Repositories 查询

  • 实体类(建立映射关系):
package com.dfbz.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;

@Data
@AllArgsConstructor
@NoArgsConstructor
@Document(indexName = "goodsindex", type = "\_doc")          // ES7.0后不支持type功能(一个索引只能有一个type,名为\_doc)
public class Goods {

    @Id
    private String id;

    @Field(index = true, store = false, fielddata = false, type = FieldType.Text, analyzer = "standard", searchAnalyzer = "standard")
    private String name;

    @Field
    private String title;

    @Field
    private Double price;

    @Field
    private String[] category;
}

  • Dao接口:
package com.dfbz.dao;

import com.dfbz.entity.Goods;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;

public interface GoodsDao extends ElasticsearchRepository<Goods,String> {
}

2.2.1 普通增删改查
  • 查询示例:
package com.dfbz.demo;

import com.dfbz.Application;
import com.dfbz.dao.GoodsDao;
import com.dfbz.entity.Goods;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.PageRequest;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.Arrays;

@SpringBootTest(classes = Application.class)
@RunWith(SpringRunner.class)
public class Demo01\_CRUD {

    @Autowired
    private GoodsDao goodsDao;


    @Test
    public void findAll() {           // query
// Iterable<Goods> goodsList = goodsDao.findAll();
        // 带分页查询
        Iterable<Goods> goodsList = goodsDao.findAll(PageRequest.of(2,1));

        for (Goods goods : goodsList) {
            System.out.println(goods);
        }
    }

    @Test
    public void findById() {           // query
        Goods goods = goodsDao.findById("1").get();

        System.out.println(goods);
    }

  • 12
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值