SpringBoot结合ElasticSearch

springBoot默认支持两种技术和ES进行交互

  1. SpringData ElasticSearch【默认】
  2. Jest【需要导入使用】详见拓展

SpringData-Elastic要点:

  • 客户端:Client节点信息: clusterNodes: clusterName
  • ElasticsearchTemplate操作es
  • 编写ElasticsearchRepository子接口

新建项目

新建项目时选择SpringBoot+Web+Nosql-->ElasticSearch;

编写配置文件

xml 复制代码
<!--Elasticsearch-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-elasticsearch<artifactId>
</dependency>
yaml 复制代码
spring:
  data:
    elasticsearch:
      repositories:
        enabled: true
      cluster-name: elasticsearch
      cluster-nodes: 127.0.0.1:9301

5、操作ElasticSearch有两种方式

复制代码
1)、编写一个ElasticsearchRepositry

​ 2)、编写一个ElasticsearchTemplate

6、ElasticsearchRepositry的操作

1)、新建一个bean类

java 复制代码
@Document(indexName = "wdjr",type="book")
public class Book {

    private Integer id;
    private String bookName;
    private String auto;
}

2)、新建一个repositry,继承ElasticsearchRepository

java 复制代码
public interface BookRepositry extends ElasticsearchRepository<Book,Integer> {
	//自定义查询方法
    public List<Book> findByBookNameLike(String bookName);
}

3)、编写测试类

java 复制代码
@Autowired
BookRepositry bookRepositry;
@Test
public void testSearch(){
    for (Book book : bookRepositry.findByBookNameLike("金")) {
        System.out.println(book);
    }

}

SpringBoot整合

4、创建并编写实体类

java 复制代码
@Data
public class User implements Serializable {
	private static final long serialVersionUID = -3843548915035470817L;
    private String name;
    private Integer age;
}

5、测试

注入 RestHighLevelClient

java 复制代码
@Autowired
public RestHighLevelClient restHighLevelClient;

ElasticSearch 的 Client

ElasticSearch 官方提供了 3 个 Client,具体如下:

  • org.elasticsearch.client.transport.TransportClient
  • org.elasticsearch.client.RestClient
  • org.elasticsearch.client.RestHighLevelClient

AbstractElasticsearchConfiguration 接口位于org.springframework.data.elasticsearch.config 包下,可以按照如下方式来使用:

java 复制代码
@Configuration
public class ESConfigutration extends AbstractElasticsearchConfiguration {
 
    @Override
    public RestHighLevelClient elasticsearchClient() {
        final ClientConfiguration clientConfiguration = ClientConfiguration.builder()
                .connectedTo("192.168.110.128:9200")
                .build();
        return RestClients.create(clientConfiguration).rest();
    }
}

如上面的代码,自定义一个配置类,继承 AbstractElasticsearchConfiguration 接口,并实现接口中定义的方法 RestHighLevelClient elasticsearchClient()。

上面的 ClientConfiguration 用来配置 ElasticSearch 客户端的属性,比如可以配置代理、连接超时时长以及 socket 超时时长等,上面的代码示例中只配置了 ElasticSearch 服务的地址和端口号。

索引的操作

1、索引的创建

java 复制代码
// 测试索引的创建, Request PUT liuyou_index
@Test
public void testCreateIndex() throws IOException {
	CreateIndexRequest request = new CreateIndexRequest("liuyou_index");
    CreateIndexResponse response = restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);    	
    System.out.println(response.isAcknowledged());// 查看是否创建成功    
    System.out.println(response);// 查看返回对象    
    restHighLevelClient.close();
}

2、索引的获取,并判断其是否存在

java 复制代码
// 测试获取索引,并判断其是否存在
@Test
	public void testIndexIsExists() throws IOException {
    	GetIndexRequest request = new GetIndexRequest("index");
        boolean exists = restHighLevelClient.indices().exists(request, RequestOptions.DEFAULT);    
        System.out.println(exists);// 索引是否存在    
        restHighLevelClient.close();
    }

3、索引的删除

java 复制代码
// 测试索引删除
@Test
public void testDeleteIndex() throws IOException {    
	DeleteIndexRequest request = new DeleteIndexRequest("liuyou_index");
    AcknowledgedResponse response = restHighLevelClient.indices().delete(request, RequestOptions.DEFAULT);  
    System.out.println(response.isAcknowledged());// 是否删除成功   
    restHighLevelClient.close();
}

文档的操作

1、文档的添加

java 复制代码
// 测试添加文档(先创建一个User实体类,添加fastjson依赖)
@Testpublic void testAddDocument() throws IOException {
	// 创建一个User对象    
	User liuyou = new User("liuyou", 18);
    // 创建请求    
    IndexRequest request = new IndexRequest("liuyou_index");
    // 制定规则 PUT /liuyou_index/_doc/1    
    request.id("1");
    // 设置文档ID 
    request.timeout(TimeValue.timeValueMillis(1000));
    // request.timeout("1s")    
    // 将我们的数据放入请求中  
    request.source(JSON.toJSONString(liuyou), XContentType.JSON); 
    // 客户端发送请求,获取响应的结果    
    IndexResponse response = restHighLevelClient.index(request, RequestOptions.DEFAULT);
    System.out.println(response.status());
    // 获取建立索引的状态信息 CREATED    
    System.out.println(response);
    // 查看返回内容 
    //IndexResponse[index=liuyou_index,type=_doc,id=1,version=1,result=created,seqNo=0,primaryTerm=1,shards={"total":2,"successful":1,"failed":0}]}

2、文档信息的获取

java 复制代码
// 测试获得文档信息
@Test
public void testGetDocument() throws IOException { 
    GetRequest request = new GetRequest("liuyou_index","1");  
    GetResponse response = restHighLevelClient.get(request, RequestOptions.DEFAULT);   
    System.out.println(response.getSourceAsString());// 打印文档内容   
    System.out.println(request);// 返回的全部内容和命令是一样的   
    restHighLevelClient.close();
}

3、文档的获取,并判断其是否存在

java 复制代码
// 获取文档,判断是否存在 get /liuyou_index/_doc/1
@Test
public void testDocumentIsExists() throws IOException { 
    GetRequest request = new GetRequest("liuyou_index", "1");  
    // 不获取返回的 _source的上下文了    
    request.fetchSourceContext(new FetchSourceContext(false));   
    request.storedFields("_none_");   
    boolean exists = restHighLevelClient.exists(request, RequestOptions.DEFAULT);   
    System.out.println(exists);
}

4、文档的更新

java 复制代码
// 测试更新文档内容
@Test
public void testUpdateDocument() throws IOException {
    UpdateRequest request = new UpdateRequest("liuyou_index", "1"); 
    User user = new User("lmk",11);   
    request.doc(JSON.toJSONString(user),XContentType.JSON); 
    UpdateResponse response = restHighLevelClient.update(request, RequestOptions.DEFAULT); 
    System.out.println(response.status()); // OK    
    restHighLevelClient.close();
}

5、文档的删除

java 复制代码
// 测试删除文档
@Test
public void testDeleteDocument() throws IOException { 
    DeleteRequest request = new DeleteRequest("liuyou_index", "1"); 
    request.timeout("1s");    
    DeleteResponse response = restHighLevelClient.delete(request, RequestOptions.DEFAULT); 
    System.out.println(response.status());// OK
}

6、文档的查询

java 复制代码
// 查询
// SearchRequest 搜索请求
// SearchSourceBuilder 条件构造
// HighlightBuilder 高亮
// TermQueryBuilder 精确查询
// MatchAllQueryBuilder
// xxxQueryBuilder ...
@Test
public void testSearch() throws IOException {
    // 1.创建查询请求对象   
    SearchRequest searchRequest = new SearchRequest();  
    // 2.构建搜索条件  
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); 
    // (1)查询条件 使用QueryBuilders工具类创建  
    // 精确查询    
    TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("name", "liuyou");  
    //       
    // 匹配查询
    //      
    MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery(); 
    // (2)其他<可有可无>:(可以参考 SearchSourceBuilder 的字段部分)  
    // 设置高亮    
    searchSourceBuilder.highlighter(new HighlightBuilder());  
    //     
    // 分页 
    //     
    searchSourceBuilder.from();
    //      
    searchSourceBuilder.size(); 
    searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
    // (3)条件投入   
    searchSourceBuilder.query(termQueryBuilder);  
    // 3.添加条件到请求   
    searchRequest.source(searchSourceBuilder); 
    // 4.客户端查询请求   
    SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT); 
    // 5.查看返回结果    
    SearchHits hits = search.getHits();  
    System.out.println(JSON.toJSONString(hits));    
    System.out.println("=======================");   
    for (SearchHit documentFields : hits.getHits()) {  
        System.out.println(documentFields.getSourceAsMap());  
    }
}
// 查询
// SearchRequest 搜索请求
// SearchSourceBuilder 条件构造
// HighlightBuilder 高亮
// TermQueryBuilder 精确查询
// MatchAllQueryBuilder
// xxxQueryBuilder ...
@Test
public void testSearch() throws IOException {
    // 1.创建查询请求对象  
    SearchRequest searchRequest = new SearchRequest();   
    // 2.构建搜索条件  
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();   
    // (1)查询条件 使用QueryBuilders工具类创建  
    // 精确查询 
    TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("name", "liuyou");   
    //      
    // 匹配查询
    //     
    MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();    
    // (2)其他<可有可无>:(可以参考 SearchSourceBuilder 的字段部分)
    // 设置高亮   
    searchSourceBuilder.highlighter(new HighlightBuilder());  
    //        
    // 分页 
    //        searchSourceBuilder.from();   
    //        searchSourceBuilder.size();  
    searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS)); 
    // (3)条件投入    
    searchSourceBuilder.query(termQueryBuilder);  
    // 3.添加条件到请求   
    searchRequest.source(searchSourceBuilder); 
    // 4.客户端查询请求  
    SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);  
    // 5.查看返回结果  
    SearchHits hits = search.getHits();    
    System.out.println(JSON.toJSONString(hits)); 
    System.out.println("=======================");  
    for (SearchHit documentFields : hits.getHits()) {      
        System.out.println(documentFields.getSourceAsMap()); 
    }
}

前面的操作都无法批量添加数据

复制代码
// 上面的这些api无法批量增加数据(只会保留最后一个source)@Testpublic void test() throws IOException {    IndexRequest request = new IndexRequest("bulk");// 没有id会自动生成一个随机ID    request.source(JSON.toJSONString(new User("liu",1)),XContentType.JSON);    request.source(JSON.toJSONString(new User("min",2)),XContentType.JSON);    request.source(JSON.toJSONString(new User("kai",3)),XContentType.JSON);    IndexResponse index = restHighLevelClient.index(request, RequestOptions.DEFAULT);    System.out.println(index.status());// created}

7、批量添加数据

复制代码
// 特殊的,真的项目一般会 批量插入数据@Testpublic void testBulk() throws IOException {    BulkRequest bulkRequest = new BulkRequest();    bulkRequest.timeout("10s");    ArrayList<User> users = new ArrayList<>();    users.add(new User("liuyou-1",1));    users.add(new User("liuyou-2",2));    users.add(new User("liuyou-3",3));    users.add(new User("liuyou-4",4));    users.add(new User("liuyou-5",5));    users.add(new User("liuyou-6",6));    // 批量请求处理    for (int i = 0; i < users.size(); i++) {        bulkRequest.add(                // 这里是数据信息                new IndexRequest("bulk")                        .id(""+(i + 1)) // 没有设置id 会自定生成一个随机id                        .source(JSON.toJSONString(users.get(i)),XContentType.JSON)        );    }    BulkResponse bulk = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);    System.out.println(bulk.status());// ok}

拓展

编写配置类方式进行配置

  • ??跟上面那个相比,这个你不build?
java 复制代码
@Configuration
public class ElasticSearchConfig { 
// 注册 rest高级客户端     
	@Bean
    public RestHighLevelClient restHighLevelClient(){
    	RestHighLevelClient client = new RestHighLevelClient(
            	RestClient.builder(new HttpHost("127.0.0.1",9200,"http"))
        );       
        return client;
    }
}

Jest

1、注释SpringDataElasticSearch的依赖,并导入Jest【5.xx】的相关依赖

xml 复制代码
        <!--   SpringData管理ElasticSearch   -->
<!--        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
        </dependency>-->

        <!-- https://mvnrepository.com/artifact/io.searchbox/jest -->
        <dependency>
            <groupId>io.searchbox</groupId>
            <artifactId>jest</artifactId>
            <version>5.3.3</version>
        </dependency>

2、修改配置文件application.yml

yaml 复制代码
spring:
  elasticsearch:
    jest:
      uris: http://192.168.179.131:9200

3、创建 bean.Article

java 复制代码
import io.searchbox.annotations.JestId;

public class Article {

    @JestId
    private Integer id;
    private String autor;
    private String title;
    private String content;

	//Getters and Setters...
}

4、运行程序

5、编写Jest Cilent的测试类

向wdjr-article中插入数据

java 复制代码
@Autowired
JestClient jestClient;

@Test
public void contextLoads() {
    //1、给Es中索引(保存)一个文档
    Article article = new Article();
    article.setId(2);
    article.setTitle("好消息");
    article.setAutor("zhangsan");
    article.setContent("Hello World");
    //构建一个索引功能
    Index index = new Index.Builder(article).index("wdjr").type("article").build();

    try {
        //执行
        jestClient.execute(index);
    } catch (IOException e) {
        e.printStackTrace();
    }

}

查询数据

java 复制代码
@Test
public void search(){
    //查询表达式
    String json = "{\n" +
            "    \"query\" : {\n" +
            "        \"match\" : {\n" +
            "            \"content\" : \"Hello\"\n" +
            "        }\n" +
            "    }\n" +
            "}";
    //构建搜索操作
    Search search = new Search.Builder(json).addIndex("wdjr").addType("article").build();

    //执行
    try {
        SearchResult result = jestClient.execute(search);
        System.out.println(result.getJsonString());
    } catch (IOException e) {
        e.printStackTrace();
    }

}