Elasticsearch Java Client API 示例

419 阅读5分钟

Elasticsearch Java Client API 使用示例,最常见的几种API,方法注释里面有对应的 REST API 和 DSL Query

public class AppTest {


    // 创建连接
    @Test
    public void testConnect(){
        // URL and API key
        String serverUrl = "http://localhost:9200";

        // Create the low-level client
        RestClient restClient = RestClient
                .builder(HttpHost.create(serverUrl))
                .build();

        // Create the transport with a Jackson mapper
        ElasticsearchTransport transport = new RestClientTransport(
                restClient, new JacksonJsonpMapper());

        // And create the API client
        ElasticsearchClient esClient = new ElasticsearchClient(transport);

        System.out.println(esClient);
    }

    public ElasticsearchClient esClient(){
        // URL and API key
        String serverUrl = "http://localhost:9200";

        // Create the low-level client
        RestClient restClient = RestClient
                .builder(HttpHost.create(serverUrl))
                .build();

        // Create the transport with a Jackson mapper
        ElasticsearchTransport transport = new RestClientTransport(
                restClient, new JacksonJsonpMapper());

        // And create the API client
        ElasticsearchClient esClient = new ElasticsearchClient(transport);

        return esClient;
    }

    /**
     * 索引操作的 API 都在 ElasticsearchIndicesClient 类中,通过 indices() 方法获得
     * @throws IOException
     */
    @Test
    public void indexTest() throws IOException, URISyntaxException {
        // 创建索引
        // PUT /test-two?pretty
        CreateIndexResponse createIndexResponse = esClient().indices()
                .create(builder -> builder.index("test-two"));
        System.out.println(createIndexResponse);

        // 删除索引
        // DELETE /test-two
        DeleteIndexResponse deleteIndexResponse = esClient().indices()
                .delete(builder -> builder.index("test-two"));
        System.out.println(deleteIndexResponse);

        // 查询索引 可以查询特定索引名称,也可以通过通配符查询,如 test-*,* 代表查询所有索引
        // GET /test-two
        GetIndexResponse getIndexResponse = esClient()
                .indices()
                .get(builder -> builder.index("test-two"));
        System.out.println(getIndexResponse);

        // whitJson 方法可以从流中创建索引
        InputStream resourceAsStream = getClass().getClassLoader().getResourceAsStream("index/test-two_mapping.json");
        esClient()
                .indices()
                .create(builder -> builder.index("test-two").withJson(resourceAsStream));

        // 创建索引的时候定义 mapping 从文件中
        URL mappingURL = getClass().getClassLoader().getResource("index/test-two.json");
        byte[] bytes = Files.readAllBytes(Paths.get(mappingURL.toURI()));
        String mappings_str = new String(bytes);
        System.out.println("mappings are: " +  mappings_str);
        JsonpMapper mapper = esClient()._transport().jsonpMapper();
        JsonParser parser = mapper.jsonProvider()
                .createParser(new StringReader( mappings_str ));
        esClient().indices().create(builder -> builder.index("test-two")
                .mappings(TypeMapping._DESERIALIZER.deserialize(parser, mapper)));

    }

    /**
     * 索引操作的 API 都在 ElasticsearchIndicesClient 类中,通过 indices() 方法获得
     * @throws IOException
     */
    @Test
    public void createIndexTest1() throws IOException {
        // 创建索引
        // PUT /test-two?pretty
        CreateIndexResponse createIndexResponse = esClient().indices()
                .create(builder -> builder.index("test-two"));
        System.out.println(createIndexResponse);

    }

    /**
     * 索引操作的 API 都在 ElasticsearchIndicesClient 类中,通过 indices() 方法获得
     * @throws IOException
     */
    @Test
    public void createIndexTest2() throws IOException {

        // whitJson 方法可以从流中创建索引
        InputStream resourceAsStream = getClass().getClassLoader().getResourceAsStream("index/test-two.json");
        esClient()
                .indices()
                .create(builder -> builder.index("test-two").withJson(resourceAsStream));

    }

    /**
     * 索引操作的 API 都在 ElasticsearchIndicesClient 类中,通过 indices() 方法获得
     * @throws IOException
     */
    @Test
    public void createIndexTest3() throws IOException, URISyntaxException {

        // 创建索引的时候定义 mapping 从文件中
        URL mappingURL = getClass().getClassLoader().getResource("index/test-two_mapping.json");
        byte[] bytes = Files.readAllBytes(Paths.get(mappingURL.toURI()));
        String mappings_str = new String(bytes);
        System.out.println("mappings are: " +  mappings_str);
        JsonpMapper mapper = esClient()._transport().jsonpMapper();
        JsonParser parser = mapper.jsonProvider()
                .createParser(new StringReader( mappings_str ));
        esClient().indices().create(builder -> builder.index("test-two")
                .mappings(TypeMapping._DESERIALIZER.deserialize(parser, mapper)));
    }

    /**
     * 索引操作的 API 都在 ElasticsearchIndicesClient 类中,通过 indices() 方法获得
     * @throws IOException
     */
    @Test
    public void deleteIndexTest() throws IOException {

        // 删除索引
        // DELETE /test-two
        DeleteIndexResponse deleteIndexResponse = esClient().indices()
                .delete(builder -> builder.index("test-two"));
        System.out.println(deleteIndexResponse);

    }

    /**
     * 索引操作的 API 都在 ElasticsearchIndicesClient 类中,通过 indices() 方法获得
     * @throws IOException
     */
    @Test
    public void searchIndexTest() throws IOException {

        // 查询索引 可以查询特定索引名称,也可以通过通配符查询,如 test-*,* 代表查询所有索引
        // GET /test-two
        GetIndexResponse getIndexResponse = esClient()
                .indices()
                .get(builder -> builder.index("test-two"));
        System.out.println(getIndexResponse);

    }


    /**
     * 索引文档
     * PUT /test-two/_doc/1?pretty
     * {
     *   "id": "1",
     *   "name": "小红",
     *   "age": 12,
     *   "address": "北京"
     * }
     * @throws IOException
     */
    @Test
    public void createDocumentTest() throws IOException {
        String index = "test-two";
        Product product = new Product("1", "小红", 12, "北京");

        // 索引文档
        IndexResponse indexResponse = esClient().index(builder -> builder.index(index)
                .id(product.getId())
                .document(product));
        System.out.println(indexResponse);

    }

    /**
     * 批量索引文档
     * @throws IOException
     */
    @Test
    public void bulkIndexDocumentTest() throws IOException {
        String index = "test-two";

        BulkRequest.Builder br = new BulkRequest.Builder();

        for (Product product : getData()) {
            br.operations(op -> op
                    .index(idx -> idx
                            .index(index)
                            .id(product.getId())
                            .document(product)
                    )
            );
        }

        BulkResponse result = esClient().bulk(br.build());
        System.out.println(result);

    }

    public List<Product> getData(){
        List<Product> data = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            Product product = new Product();
            product.setId(UUID.randomUUID().toString());
            product.setName("name:"+i);
            product.setAge(i);
            product.setAddress("address:"+i);
            data.add(product);
        }

        return data;
    }

    /**
     * 根据id删除文档
     * DELETE /test-two/_doc/1
     * @throws IOException
     */
    @Test
    public void deleteDocumentTest() throws IOException {
        String index = "test-two";
        String id = "1";

        // 删除文档
        DeleteResponse delete = esClient().delete(builder -> builder.index(index).id(id));
        System.out.println(delete);

    }

    /**
     * 更新文档
     * POST /test-two/_update/1
     * {
     *   "doc": {
     *     "id": "1",
     *     "name": "小红",
     *     "age": 12,
     *     "address": "天津"
     *   }
     * }
     * @throws IOException
     */
    @Test
    public void updateDocumentTest() throws IOException {
        String index = "test-two";
        Product product = new Product("1", "小红", 12, "长沙");

        // 更新文档
        UpdateResponse<Product> update = esClient()
                .update(builder -> builder.index(index)
                        .id(product.getId())
                        .doc(product), Product.class);
        System.out.println(update);

    }

    /**
     * 通过id查询文档
     * GET /test-two/_doc/1?pretty
     */
    @Test
    public void searchDocumentById() throws IOException {
        String index = "test-two";
        String id = "1";

        // 查询文档
        GetResponse<Product> getResponse = esClient().get(builder -> builder.index(index).id(id), Product.class);
        System.out.println(getResponse);
    }

    /**
     * 查询所有
     * GET /test-one/_search
     * {
     *   "query": {
     *     "match_all": {}
     *   }
     * }
     */
    @Test
    public void searchDocumentAll() throws IOException {
        String index = "test-two";

        SearchResponse<Product> search = esClient().search(builder -> builder.index(index)
                .query(builder1 -> builder1.matchAll(builder2 -> builder2)), Product.class);
        List<Hit<Product>> hits = search.hits().hits();
        System.out.println(hits);
    }

    /**
     * 全文搜索 单字段匹配
     * GET /test-two/_search
     * {
     *   "query": {
     *     "match": {
     *       "name": "1"
     *     }
     *   }
     * }
     * @throws IOException
     */
    @Test
    public void matchSingleFieldTest() throws IOException {
        String index = "test-two";

        SearchResponse<Product> search = esClient().search(builder -> builder.index(index)
                .query(builder1 -> builder1.match(builder2 -> builder2.field("name").query("1"))), Product.class);
        List<Hit<Product>> hits = search.hits().hits();
        System.out.println(hits);
    }

    /**
     * 全文搜索 多字段匹配
     * GET /test-two/_search
     * {
     *   "query": {
     *     "multi_match": {
     *       "query": "1",
     *       "fields": ["name", "id"]
     *     }
     *   }
     * }
     * @throws IOException
     */
    @Test
    public void matchMultiFieldTest() throws IOException {
        String index = "test-two";

        SearchResponse<Product> search = esClient().search(builder -> builder.index(index)
                .query(builder1 -> builder1.multiMatch(builder2 -> builder2
                        .fields(Arrays.asList("id", "name"))
                        .query("1"))), Product.class);
        List<Hit<Product>> hits = search.hits().hits();
        System.out.println(hits);
    }

    /**
     * 精准查询 单字段短语查询
     * GET /test-two/_search
     * {
     *   "query": {
     *     "term": {
     *       "id": {
     *         "value": "1"
     *       }
     *     }
     *   }
     * }
     * @throws IOException
     */
    @Test
    public void termTest() throws IOException {
        String index = "test-two";

        SearchResponse<Product> search = esClient().search(
                builder -> builder
                        .index(index)
                        .query(builder1 -> builder1.term(builder2 -> builder2.field("id").value("1")))
                , Product.class
        );
        List<Hit<Product>> hits = search.hits().hits();
        System.out.println(hits);
    }

    /**
     * 精准查询 多字段短语查询
     * GET /test-two/_search
     * {
     *   "query": {
     *     "terms": {
     *       "id": [
     *         "1",
     *         "a9383771-8bff-49fd-9e61-a4b8a00583de"
     *       ]
     *     }
     *   }
     * }
     * @throws IOException
     */
    @Test
    public void termsTest() throws IOException {
        String index = "test-two";

        SearchResponse<Product> search = esClient().search(
                builder -> builder
                        .index(index)
                        .query(builder1 -> builder1.terms(
                                builder2 -> builder2.field("id")
                                        .terms(builder3 -> builder3
                                                .value(
                                                        Arrays.asList(FieldValue.of("1")
                                                                , FieldValue.of("a9383771-8bff-49fd-9e61-a4b8a00583de")))
                                        )
                                )
                        )
                , Product.class
        );
        List<Hit<Product>> hits = search.hits().hits();
        System.out.println(hits);
    }

    /**
     * 精准查询 范围查询
     * GET /test-two/_search
     * {
     *   "query": {
     *     "range": {
     *       "age": {
     *         "gte": 10,
     *         "lte": 20
     *       }
     *     }
     *   }
     * }
     * @throws IOException
     */
    @Test
    public void rangeTest() throws IOException {
        String index = "test-two";

        SearchResponse<Product> search = esClient().search(builder -> builder.index(index)
                        .query(
                                builder1 -> builder1.range(
                                        builder2 -> builder2.field("age")
                                                .gte(JsonData.of(10))
                                                .lte(JsonData.of(20))
                                )
                        )
                , Product.class
        );
        List<Hit<Product>> hits = search.hits().hits();
        System.out.println(hits);
    }

    /**
     * 分页查询 from size
     * GET /test-one/_search
     * {
     *   "query": {
     *     "match_all": {}
     *   },
     *   "from": 0,
     *   "size": 2
     * }
     * @throws IOException
     */
    @Test
    public void pageTest() throws IOException {
        String index = "test-two";

        SearchResponse<Product> search = esClient().search(builder -> builder.index(index)
                        .query(
                                builder1 -> builder1.matchAll(builder2 -> builder2)
                        ).from(0).size(2)
                , Product.class
        );
        List<Hit<Product>> hits = search.hits().hits();
        System.out.println(hits);
    }

    /**
     * 复合查询 bool
     * GET /test-two/_search
     * {
     *   "query": {
     *     "bool": {
     *       "must": [
     *         {
     *           "match": {
     *             "name": "1"
     *           }
     *         }
     *       ],
     *       "should": [
     *         {
     *           "match": {
     *             "id": "1"
     *           }
     *         },
     *         {
     *           "term": {
     *             "age": {
     *               "value": 12
     *             }
     *           }
     *         }
     *       ]
     *     }
     *   }
     * }
     * @throws IOException
     */
    @Test
    public void boolTest() throws IOException {
        String index = "test-two";

        BoolQuery.Builder boolQueryBuilder = new BoolQuery.Builder();
        List<Query> queryList = new ArrayList<>();
        queryList.add(Query.of(builder -> builder.match(builder1 -> builder1.field("name").query("1"))));
        boolQueryBuilder.must(queryList);
        queryList = new ArrayList<>();
        queryList.add(Query.of(builder -> builder.match(builder1 -> builder1.field("id").query("1"))));
        queryList.add(Query.of(builder -> builder.term(builder1 -> builder1.field("age").value(12))));
        boolQueryBuilder.should(queryList);
        SearchResponse<Product> search = esClient().search(builder -> builder.index(index)
                        .query(builder1 -> builder1.bool(boolQueryBuilder.build()))
                , Product.class
        );
        List<Hit<Product>> hits = search.hits().hits();
        System.out.println(hits);
    }

    /**
     * 聚合操作
     * GET /test-two/_search
     * {
     *   "size": 0,
     *   "aggs": {
     *     "aggs_name": {
     *       "terms": {
     *         "field": "name.keyword"
     *       }
     *     }
     *   }
     * }
     */
    @Test
    public void aggsTest() throws IOException {
        String index = "test-two";
        String aggs_name = "aggs_name";

        SearchResponse<Product> searchResponse = esClient().search(builder -> builder.index(index)
                        .aggregations(aggs_name
                                , builder1 -> builder1.terms(builder2 -> builder2.field("name.keyword")))
                , Product.class
        );
        Aggregate aggregate = searchResponse.aggregations().get(aggs_name);
        System.out.println(aggregate);

    }

    /**
     * 高亮
     * GET /test-two/_search
     * {
     *   "query": {
     *     "match": {
     *       "name": "1"
     *     }
     *   },
     *   "highlight": {
     *     "fields": {
     *       "name": {}
     *     }
     *   }
     * }
     */
    @Test
    public void heightLightTest() throws IOException {
        String index = "test-two";

        SearchResponse<Product> searchResponse = esClient().search(builder -> builder.index(index)
                        .query(builder1 -> builder1.match(builder2 -> builder2.field("name").query("1")))
                        .highlight(builder1 -> builder1.fields("name", builder2 -> builder2))
                , Product.class
        );
        System.out.println(searchResponse);
    }

}