【微服务】java 操作elasticsearch详细总结

108 阅读9分钟

一、前言 上一篇我们通过kibana的可视化界面,对es的索引以及文档的常用操作做了毕竟详细的总结,本篇将介绍如何使用java完成对es的操作,这也是实际开发中将要涉及到的。

二、java操作es的常用模式 目前,开发中使用java操作es,不管是框架集成,还是纯粹的使用es的api,主要通过下面两种方式:

rest-api,主流的像 RestHighLevelClient ;

与springboot集成时的jpa操作,主要是 ElasticsearchRepository 相关的api;

上面两种模式的api在开发中都可以方便的使用,相比之下,RestHighLevelClient相关的api灵活性更高,而ElasticsearchRepository 底层做了较多的封装,学习和使用的成本更低,上手更快。

接下来将对上面的两种操作模式做一个详细的总结,本篇所述的es基于7.6.2版本,配合的kibana也为7.6.2版本。

三、rest-api 操作 1、前置准备 导入依赖 导入核心依赖,主要是es的rest依赖,其他的可以根据自己的需要导入;

    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-api</artifactId>
        <version>2.11.2</version>
    </dependency>

    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-core</artifactId>
        <version>2.11.2</version>
    </dependency>

    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-core</artifactId>
        <version>2.8.2</version>
    </dependency>

    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-jcl</artifactId>
        <version>2.11.2</version>
    </dependency>

    <dependency>
        <groupId>commons-logging</groupId>
        <artifactId>commons-logging</artifactId>
        <version>1.2</version>
    </dependency>

    <dependency>
        <groupId>org.elasticsearch</groupId>
        <artifactId>elasticsearch</artifactId>
        <version>7.6.2</version>
    </dependency>

    <dependency>
        <groupId>org.elasticsearch.client</groupId>
        <artifactId>elasticsearch-rest-high-level-client</artifactId>
        <version>7.6.2</version>
    </dependency>

    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.9.9</version>
    </dependency>

    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>


</dependencies>

es连接测试 为了确保后续的所有实验能够正常进行,建议先通过下面的程序测试下是否能够连接es服务;

import org.apache.http.HttpHost; import org.elasticsearch.client.RestClient; import org.elasticsearch.client.RestHighLevelClient;

import java.io.IOException;

public class EsClientTest {

public static void main(String[] args) throws IOException {
    RestHighLevelClient esClient = new RestHighLevelClient(
            RestClient.builder(new HttpHost("IP",9200,"http"))
    );
    System.out.println("success");
    esClient.close();
}

}

运行上面的代码,出现下面的效果说明连接成功

2、索引相关操作api的使用 为了减少连接相关的编码,我们将es的client提出到全局的静态变量中,其他方法中就可以直接引用了

public static RestHighLevelClient esClient;

static {
    esClient = new RestHighLevelClient(
            RestClient.builder(new HttpHost("IP", 9200, "http"))
    );
}

2.1 创建索引 /** * 创建索引 * @throws IOException */ public static void createIndex() throws IOException { CreateIndexRequest createIndexRequest = new CreateIndexRequest("user"); CreateIndexResponse indexResponse = esClient.indices().create(createIndexRequest, RequestOptions.DEFAULT); boolean acknowledged = indexResponse.isAcknowledged(); System.out.println("索引创建状态:" + acknowledged); } main方法中调用方法即可

public static void main(String[] args) throws IOException { System.out.println("connect success"); createIndex(); esClient.close(); } 运行main创建索引

通过kibana查询确认索引是否创建成功

2.2 获取索引 /** * 索引信息查询 * @throws IOException */ public static void getIndex() throws IOException { GetIndexRequest getIndexRequest = new GetIndexRequest("user"); GetIndexResponse getIndexResponse = esClient.indices().get(getIndexRequest, RequestOptions.DEFAULT); System.out.println(getIndexResponse.getAliases()); System.out.println(getIndexResponse.getMappings()); System.out.println(getIndexResponse.getSettings()); }

2.3 删除索引 /** * 删除索引 * @throws IOException */ public static void deleteIndex() throws IOException { DeleteIndexRequest getIndexRequest = new DeleteIndexRequest("user"); AcknowledgedResponse delete = esClient.indices().delete(getIndexRequest, RequestOptions.DEFAULT); System.out.println("索引删除状态:" + delete.isAcknowledged()); }

3、文档常用操作api的使用 在实际开发过程中,对于文档的操作更为的频繁,接下来演示与es文档相关的操作api。

前置准备 public static ObjectMapper objectMapper = new ObjectMapper();

public static RestHighLevelClient esClient;
static {
    esClient = new RestHighLevelClient(
            RestClient.builder(new HttpHost("IP", 9200, "http"))
    );
}

用于测试使用的对象

public class User {

private String name;
private String sex;
private Integer age;

private Integer salary;

public User() {
}

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

public Integer getSalary() {
    return salary;
}

public void setSalary(Integer salary) {
    this.salary = salary;
}

public String getName() {
    return name;
}

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

public String getSex() {
    return sex;
}

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

public Integer getAge() {
    return age;
}

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

}

3.1 索引添加文档 注意:实际开发中,user对象应该作为参数传入【可以基于此做进一步的封装】

/**
 * 添加数据
 * @throws Exception
 */
public static void add() throws Exception{
    IndexRequest indexRequest = new IndexRequest();
    indexRequest.index("user").id("1008");
    User user = new User();
    user.setName("孙二娘");
    user.setAge(23);
    user.setSex("女");
    user.setSalary(7000);

    String userData = objectMapper.writeValueAsString(user);
    indexRequest.source(userData,XContentType.JSON);
    //插入数据
    IndexResponse response = esClient.index(indexRequest, RequestOptions.DEFAULT);
    System.out.println(response.status());
    System.out.println(response.getResult());
}

在main方法调用执行下该方法

public static void main(String[] args) throws Exception { add(); esClient.close(); }

可以通过kibana查询检查下数据是否添加成功

3.2 修改文档 /** * 修改数据 * @throws Exception */ public static void update() throws Exception{ UpdateRequest request = new UpdateRequest(); request.index("user").id("1008"); request.doc(XContentType.JSON,"name","母夜叉"); //插入数据 UpdateResponse response = esClient.update(request, RequestOptions.DEFAULT); System.out.println(response.getResult()); }

3.3 删除文档 /** * 删除 * @throws Exception */ public static void delete() throws Exception{ DeleteRequest request = new DeleteRequest(); request.index("user").id("1008"); //插入数据 DeleteResponse delete = esClient.delete(request, RequestOptions.DEFAULT); System.out.println(delete.getResult()); }

3.4 批量添加文档 有些情况下,单条插入效率太低,可以使用es的批量插入功能一次性添加多条数据

/**
 * 批量添加
 * @throws Exception
 */
public static void batchInsert() throws Exception{

    BulkRequest bulkRequest = new BulkRequest();

    User user1 = new User("关羽","男",33,5500);
    String userData1 = objectMapper.writeValueAsString(user1);
    IndexRequest indexRequest1 = new IndexRequest().index("user").id("1002").source(userData1, XContentType.JSON);

    bulkRequest.add(indexRequest1);

    User user2 = new User("黄忠","男",50,8000);
    String userData2 = objectMapper.writeValueAsString(user2);
    IndexRequest indexRequest2 = new IndexRequest().index("user").id("1003").source(userData2, XContentType.JSON);
    bulkRequest.add(indexRequest2);

    User user3 = new User("黄忠2","男",49,10000);
    String userData3 = objectMapper.writeValueAsString(user3);
    IndexRequest indexRequest3 = new IndexRequest().index("user").id("1004").source(userData3, XContentType.JSON);
    bulkRequest.add(indexRequest3);

    User user4 = new User("赵云","男",33,12000);
    String userData4 = objectMapper.writeValueAsString(user4);
    IndexRequest indexRequest4 = new IndexRequest().index("user").id("1005").source(userData4, XContentType.JSON);
    bulkRequest.add(indexRequest4);

    User user5 = new User("马超","男",38,20000);
    String userData5 = objectMapper.writeValueAsString(user5);
    IndexRequest indexRequest5 = new IndexRequest().index("user").id("1006").source(userData5, XContentType.JSON);
    bulkRequest.add(indexRequest5);

    User user6 = new User("关羽","男",41,27000);
    String userData6 = objectMapper.writeValueAsString(user6);
    IndexRequest indexRequest6 = new IndexRequest().index("user").id("1007").source(userData6, XContentType.JSON);
    bulkRequest.add(indexRequest6);

    BulkResponse bulkResponse = esClient.bulk(bulkRequest, RequestOptions.DEFAULT);
    System.out.println(bulkResponse.status());
    System.out.println(bulkResponse.getItems());
}

3.5 批量删除 可以通过批量操作一次性删除多条数据

/**
 * 批量删除
 * @throws Exception
 */
public static void batchDelete() throws Exception{
    BulkRequest bulkRequest = new BulkRequest();
    DeleteRequest indexRequest1 = new DeleteRequest().index("user").id("1002");
    DeleteRequest indexRequest2 = new DeleteRequest().index("user").id("1003");
    DeleteRequest indexRequest3 = new DeleteRequest().index("user").id("1004");
    DeleteRequest indexRequest4 = new DeleteRequest().index("user").id("1005");
    DeleteRequest indexRequest5 = new DeleteRequest().index("user").id("1006");
    DeleteRequest indexRequest6 = new DeleteRequest().index("user").id("1007");

    bulkRequest.add(indexRequest1);
    bulkRequest.add(indexRequest2);
    bulkRequest.add(indexRequest3);
    bulkRequest.add(indexRequest4);
    bulkRequest.add(indexRequest5);
    bulkRequest.add(indexRequest6);

    BulkResponse bulkResponse = esClient.bulk(bulkRequest, RequestOptions.DEFAULT);
    System.out.println(bulkResponse.status());
    System.out.println(bulkResponse.getItems());
}

4、文档搜索相关api的使用 我们知道es最强大的功能就是文档检索了,接下来演示下与es文档查询相关的常用API的操作;

4.1 查询某个索引下的所有数据 /** * 查询某个索引下的所有数据 * @throws Exception */ public static void searchIndexAll() throws Exception{ SearchRequest request = new SearchRequest(); request.indices("user"); // 索引中的全部数据查询 SearchSourceBuilder query = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery()); request.source(query); SearchResponse response = esClient.search(request, RequestOptions.DEFAULT); SearchHits hits = response.getHits(); for (SearchHit searchHit : hits){ System.out.println(searchHit.getSourceAsString()); } }

执行一下对该方法的调用

这个效果和在kibana中下面的操作效果是一样的

4.2 批量查询多条数据 针对那种需要一次性查出多条数据的场景可以考虑使用

    MultiGetRequest multiGetRequest = new MultiGetRequest();
    multiGetRequest.add("user", "1002");
    multiGetRequest.add("user", "1003");
    MultiGetResponse responses = esClient
            .mget(multiGetRequest, RequestOptions.DEFAULT);

    Iterator<MultiGetItemResponse> iterator = responses.iterator();
    while (iterator.hasNext()){
        MultiGetItemResponse next = iterator.next();
        System.out.println(next.getResponse().getSourceAsString());
    }

4.3 根据条件精准查询 根据性别查询,有点类似于mysql 中的 where sex='女' 这样的效果

    TermQueryBuilder ageQueryBuilder = QueryBuilders.termQuery("sex", "女");
    SearchSourceBuilder query = new SearchSourceBuilder().query(ageQueryBuilder);
    request.source(query);
    SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
    System.out.println(response.getHits().getHits());
    System.out.println(response.getHits().getTotalHits());
    SearchHits hits = response.getHits();
    for (SearchHit searchHit : hits){
        System.out.println(searchHit.getSourceAsString());
    }

4.4 分页查询 考察from + size的使用

    SearchSourceBuilder sourceBuilder = new                         
    SearchSourceBuilder().query(QueryBuilders.matchAllQuery());
    sourceBuilder.from(0).size(3);
    request.source(sourceBuilder);
    SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
    System.out.println(response.getHits().getHits());
    System.out.println(response.getHits().getTotalHits());
    SearchHits hits = response.getHits();
    for (SearchHit searchHit : hits){
        System.out.println(searchHit.getSourceAsString());
    }

4.5 查询结果按照某个字段进行排序 将查询结果按照age进行排序

    SearchSourceBuilder sourceBuilder = new     
    SearchSourceBuilder().query(QueryBuilders.matchAllQuery());
    sourceBuilder.sort("age",SortOrder.ASC);
    request.source(sourceBuilder);
    SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
    System.out.println(response.getHits().getHits());
    System.out.println(response.getHits().getTotalHits());
    SearchHits hits = response.getHits();
    for (SearchHit searchHit : hits){
        System.out.println(searchHit.getSourceAsString());
    }

4.6 查询结果过滤某些字段 类似于mysql中只查询某个表的部分字段

    SearchSourceBuilder sourceBuilder = new         
    SearchSourceBuilder().query(QueryBuilders.matchAllQuery());
    request.source(sourceBuilder);
    String[] includes = {"name","sex"};
    String[] excludes = {"age"};
    sourceBuilder.fetchSource(includes,excludes);
    SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
    System.out.println(response.getHits().getHits());
    System.out.println(response.getHits().getTotalHits());
    SearchHits hits = response.getHits();
    for (SearchHit searchHit : hits){
        System.out.println(searchHit.getSourceAsString());
    }

4.7 多条件查询 es可以像mysql那样组合多个条件进行查询,考察对BoolQuery的使用,如下:查询性别为难男,年龄在35到45之间的用户;

    BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
    boolQueryBuilder.must(QueryBuilders.matchQuery("sex","男"));
    boolQueryBuilder.must(QueryBuilders.rangeQuery("age").lt(45).gt(35));
    sourceBuilder.query(boolQueryBuilder);
    request.source(sourceBuilder);
    SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);

    System.out.println(response.getHits().getHits());
    System.out.println(response.getHits().getTotalHits());
    SearchHits hits = response.getHits();
    for (SearchHit searchHit : hits){
        System.out.println(searchHit.getSourceAsString());
    }

4.8 范围查询 SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); RangeQueryBuilder rangeQueryBuilder =
QueryBuilders.rangeQuery("age").gte(35).lte(45); sourceBuilder.query(rangeQueryBuilder); request.source(sourceBuilder); SearchResponse response = esClient.search(request, RequestOptions.DEFAULT); System.out.println(response.getHits().getHits()); System.out.println(response.getHits().getTotalHits()); SearchHits hits = response.getHits(); for (SearchHit searchHit : hits){ System.out.println(searchHit.getSourceAsString()); }

4.9 模糊查询 SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); FuzzyQueryBuilder fuzzyQueryBuilder = QueryBuilders.fuzzyQuery("name", "黄忠") .fuzziness(Fuzziness.ONE); sourceBuilder.query(fuzzyQueryBuilder); request.source(sourceBuilder); SearchResponse response = esClient.search(request, RequestOptions.DEFAULT); System.out.println(response.getHits().getHits()); System.out.println(response.getHits().getTotalHits()); SearchHits hits = response.getHits(); for (SearchHit searchHit : hits){ System.out.println(searchHit.getSourceAsString()); }

4.10 高亮查询 SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); TermQueryBuilder ageQueryBuilder = QueryBuilders.termQuery("age", 33); HighlightBuilder highlightBuilder = new HighlightBuilder(); highlightBuilder.preTags(""); highlightBuilder.postTags(""); highlightBuilder.field("name"); sourceBuilder.highlighter(highlightBuilder); sourceBuilder.query(ageQueryBuilder); request.source(sourceBuilder); SearchResponse response = esClient.search(request, RequestOptions.DEFAULT); System.out.println(response.getHits().getHits()); System.out.println(response.getHits().getTotalHits()); SearchHits hits = response.getHits(); for (SearchHit searchHit : hits){ System.out.println(searchHit.getSourceAsString()); }

4.11 多字段查询multi_match 这个用法表示从多个字段中匹配某个关键字

    SearchSourceBuilder builder = new SearchSourceBuilder();
    MultiMatchQueryBuilder multiMatchQuery = QueryBuilders.multiMatchQuery("黄忠","name", "sex");
    multiMatchQuery.operator(Operator.OR);
    builder.query(multiMatchQuery);
    request.source(builder);
    SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
    System.out.println(response.getHits().getHits());
    System.out.println(response.getHits().getTotalHits());
    SearchHits hits = response.getHits();
    for (SearchHit searchHit : hits){
        System.out.println(searchHit.getSourceAsString());
    }

4.12 聚合查询 SearchSourceBuilder builder = new SearchSourceBuilder(); AggregationBuilder aggregationBuilder = AggregationBuilders.max("maxAge").field("age"); builder.aggregation(aggregationBuilder); request.source(builder); SearchResponse response = esClient.search(request, RequestOptions.DEFAULT); System.out.println(response.getHits().getHits()); System.out.println(response.getHits().getTotalHits()); SearchHits hits = response.getHits(); for (SearchHit searchHit : hits){ System.out.println(searchHit.getSourceAsString()); } 4.13 分组查询 SearchSourceBuilder builder = new SearchSourceBuilder(); AggregationBuilder aggregationBuilder = AggregationBuilders.terms("ageGroup").field("age"); builder.aggregation(aggregationBuilder); request.source(builder);

    SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
    System.out.println(response.getHits().getHits());
    System.out.println(response.getHits().getTotalHits());
    SearchHits hits = response.getHits();
    for (SearchHit searchHit : hits){
        System.out.println(searchHit.getSourceAsString());
    }

四、与springboot 整合 es提供了与spring,springboot快速整合的第三方SDK,接下来以spring-data为例进行说明;

spring-boot-starter-data-elasticsearch 与spring其他相关的jpa方式使用类似,封装了丰富的API接口,客户只需要继承其提供的接口,就能方便的使用内置的API

前置准备 本地创建一个maven工程

1、导入核心依赖 org.springframework.boot spring-boot-starter-parent 2.3.6.RELEASE

<dependencies>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <scope>runtime</scope>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-test</artifactId>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
    </dependency>
</dependencies>

2、核心配置文件

es 服务地址

elasticsearch.host=IP

es 服务端口

elasticsearch.port=9200

配置日志级别,开启 debug 日志

logging.level.com.congge=debug 整合过程 1、创建一个实体类 该实体类属于连接es文档与客户端的一个中间转换层,使用过jpa或者mybatis-plus的同学对这个应该不陌生;

import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.ToString; 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 @NoArgsConstructor @AllArgsConstructor @ToString @Document(indexName = "shopping", shards = 3, replicas = 1) public class Product { //必须有 id,这里的 id 是全局唯一的标识,等同于 es 中的"_id" @Id private Long id;//商品唯一标识

/**
 * type : 字段数据类型
 * analyzer : 分词器类型
 * index : 是否索引(默认:true)
 * Keyword : 短语,不进行分词
 */
@Field(type = FieldType.Text, analyzer = "ik_max_word")
private String title;//商品名称

@Field(type = FieldType.Keyword)
private String category;//分类名称

@Field(type = FieldType.Double)
private Double price;//商品价格

@Field(type = FieldType.Keyword, index = false)
private String images;//图片地址

}

2、提供一个接口,继承ElasticsearchRepository import com.congge.entity.Product; import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; import org.springframework.stereotype.Repository;

@Repository public interface ProductDao extends ElasticsearchRepository<Product, Long>{

} 3、核心配置类 import lombok.Data; import org.apache.http.HttpHost; import org.elasticsearch.client.RestClient; import org.elasticsearch.client.RestClientBuilder; import org.elasticsearch.client.RestHighLevelClient; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Configuration; //import org.springframework.data.elasticsearch.config.AbstractElasticsearchConfiguration;

@ConfigurationProperties(prefix = "elasticsearch") @Configuration @Data public class EsConfig extends com.congge.config.AbstractElasticsearchConfiguration {

private String host ;
private Integer port ;

//重写父类方法
@Override
public RestHighLevelClient elasticsearchClient() {
    RestClientBuilder builder = RestClient.builder(new HttpHost(host, port));
    RestHighLevelClient restHighLevelClient = new
            RestHighLevelClient(builder);
    return restHighLevelClient;
}

}

import org.elasticsearch.client.RestHighLevelClient; import org.springframework.context.annotation.Bean; import org.springframework.data.elasticsearch.config.ElasticsearchConfigurationSupport; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate; import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;

public abstract class AbstractElasticsearchConfiguration extends ElasticsearchConfigurationSupport {

//需重写本方法
public abstract RestHighLevelClient elasticsearchClient();

@Bean(name = { "elasticsearchOperations", "elasticsearchTemplate" })
public ElasticsearchOperations elasticsearchOperations(ElasticsearchConverter elasticsearchConverter) {
    return new ElasticsearchRestTemplate(elasticsearchClient(), elasticsearchConverter);
}

}

模拟测试 接下来通过junit的方式进行测试

1、索引相关的操作测试 import com.congge.entity.Product; 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.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class) @SpringBootTest public class EsIndexTest {

//注入 ElasticsearchRestTemplate
@Autowired
private ElasticsearchRestTemplate elasticsearchRestTemplate;

//创建索引并增加映射配置
@Test
public void createIndex(){
    //创建索引,系统初始化会自动创建索引
    System.out.println("创建索引");
}

@Test
public void deleteIndex(){
    //创建索引,系统初始化会自动创建索引
    boolean flg = elasticsearchRestTemplate.deleteIndex(Product.class);
    System.out.println("删除索引 = " + flg);
}

}

基于spring-data的方式,在工程启动的时候,会自动读取实体类相关的注解,自动完成索引的创建,运行下创建索引的测试方法;

然后去到kibana上面确认下是否创建成功;

2、文档相关的操作测试 该测试类中列举了常用的增删改查操作

import com.congge.dao.ProductDao; import com.congge.entity.Product; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.index.query.TermQueryBuilder; 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.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort; import org.springframework.test.context.junit4.SpringRunner;

import java.util.ArrayList; import java.util.List;

@RunWith(SpringRunner.class) @SpringBootTest public class EsDocTest {

@Autowired
private ProductDao productDao;

/**
 * 新增
 */
@Test
public void save() {
    Product product = new Product();
    product.setId(2L);
    product.setTitle("ipad mini");
    product.setCategory("ipad");
    product.setPrice(1998.0);
    product.setImages("http://ipad.jpg");
    productDao.save(product);
}


//修改
@Test
public void update(){
    Product product = new Product();
    product.setId(2L);
    product.setTitle("iphone");
    product.setCategory("mobile");
    product.setPrice(6999.0);
    product.setImages("http://www.phone.jpg");
    productDao.save(product);
}

//根据 id 查询
@Test
public void findById(){
    Product product = productDao.findById(2L).get();
    System.out.println(product);
}

//查询所有
@Test
public void findAll(){
    Iterable<Product> products = productDao.findAll();
    for (Product product : products) {
        System.out.println(product);
    }
}

//删除
@Test
public void delete(){
    Product product = new Product();
    product.setId(2L);
    productDao.delete(product);
}

//批量新增
@Test
public void saveAll(){
    List<Product> productList = new ArrayList<>();
    for (int i = 0; i < 10; i++) {
        Product product = new Product();
        product.setId(Long.valueOf(i));
        product.setTitle("iphone" + i);
        product.setCategory("mobile");
        product.setPrice(5999.0 + i);
        product.setImages("http://www.phone.jpg");
        productList.add(product);
    }
    productDao.saveAll(productList);
}

//分页查询
@Test
public void findByPageable(){
    //设置排序(排序方式,正序还是倒序,排序的 id)
    Sort sort = Sort.by(Sort.Direction.DESC,"id");
    int currentPage=0;//当前页,第一页从 0 开始, 1 表示第二页
    int pageSize = 5;//每页显示多少条
    //设置查询分页
    PageRequest pageRequest = PageRequest.of(currentPage, pageSize,sort);
    //分页查询
    Page<Product> productPage = productDao.findAll(pageRequest);
    for (Product Product : productPage.getContent()) {
        System.out.println(Product);
    }
}

/**
 * term 查询
 * search(termQueryBuilder) 调用搜索方法,参数查询构建器对象
 */
@Test
public void termQuery(){
    TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("title", "iphone");
    Iterable<Product> products = productDao.search(termQueryBuilder);
    for (Product product : products) {
        System.out.println(product);
    }
}

/**
 * term 查询加分页
 */
@Test
public void termQueryByPage(){
    int currentPage= 0 ;
    int pageSize = 5;
    //设置查询分页
    PageRequest pageRequest = PageRequest.of(currentPage, pageSize);
    TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("title", "phone");
    Iterable<Product> products =
            productDao.search(termQueryBuilder,pageRequest);
    for (Product product : products) {
        System.out.println(product);
    }
}

}

测试其中批量新增的方法