ElasticSearch学习笔记(5)——SpringBoot整合ElasticSearch
本节主要介绍SpringBoot与ElasticSearch的整合,并实现简单的CRUD。
概述
SpringBoot与ElasticSearch的整合主要有两种方式:
- Spring将ElasticSearch的操作也封装到了Spring Data项目中,dao接口继承 ElasticsearchRepository 即可;
- 使用Spring提供的ElasticsearchTemplate模板类,在Service类中直接注入ElasticsearchTemplate对象即可。
具体操作
引入spring-boot-starter-data-elasticsearch依赖
<!--ElasticSearch依赖--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency>
添加ElaticSearch配置
spring: data: elasticsearch: cluster-name: elasticsearch #集群名称,默认即为 elasticsearch cluster-nodes: 127.0.0.1:9300 #配置es节点信息,多个节点用逗号分隔。如果没有指定,则启动ClientNode。注:ES中API的端口号要写TransportService服务的端口,默认为9300
实体类
/** * @Auther: ZhangShenao * @Date: 2018/8/24 10:29 * @Description:Book实体 * 加上了@Document注解之后,默认情况下这个实体中所有的属性都会被建立索引、并且分词 */ @Document(indexName = "product", type = "book") @Getter @Setter public class Book { @Id String id; String name; String message; String type; }
使用ElasticsearchRepository的Dao接口ElasticsearchRepository
/** * @Auther: ZhangShenao * @Date: 2018/8/24 10:32 * @Description:Book Dao接口,继承ElasticsearchRepository实现EalsticSearch操作 */ public interface BookDao extends ElasticsearchRepository<Book,String> { }
Controller
这里为了简单演示,就不编写Service代码了,直接在Controller中操作Dao
/** * @Auther: ZhangShenao * @Date: 2018/8/24 10:36 * @Description:直接使用ElasticsearchRepository操作ElasticSearch */ @RestController @RequestMapping("/book") public class BookController { @Autowired private BookDao bookDao; /** * 根据id查询 */ @GetMapping("/get/{id}") public BookEntity getBookById(@PathVariable String id) { return bookDao.findOne(id); } /** * 全文检索 */ @GetMapping("/select/{search}") public List<BookEntity> search(@PathVariable String search) { QueryStringQueryBuilder builder = new QueryStringQueryBuilder(search); Iterable<BookEntity> searchResult = bookDao.search(builder); if (searchResult == null){ return Collections.emptyList(); } Iterator<BookEntity> iterator = searchResult.iterator(); List<BookEntity> books = new ArrayList<>(); while (iterator.hasNext()) { books.add(iterator.next()); } return books; } /** * 分页查询 */ @GetMapping("/{page}/{size}/{search}") public List<BookEntity> searchByPage(@PathVariable Integer page, @PathVariable Integer size, @PathVariable String search) { // 分页参数 Pageable pageable = new PageRequest(page, size); // 分数,并自动按分排序 FunctionScoreQueryBuilder functionScoreQueryBuilder = QueryBuilders.functionScoreQuery() .add(QueryBuilders.boolQuery().should(QueryBuilders.matchQuery("name", search)), ScoreFunctionBuilders.weightFactorFunction(1000)) // 权重:name 1000分 .add(QueryBuilders.boolQuery().should(QueryBuilders.matchQuery("message", search)), ScoreFunctionBuilders.weightFactorFunction(100)); // 权重:message 100分 // 分数、分页 SearchQuery searchQuery = new NativeSearchQueryBuilder().withPageable(pageable) .withQuery(functionScoreQueryBuilder).build(); Page<BookEntity> searchPageResults = bookDao.search(searchQuery); return searchPageResults.getContent(); } /** * 添加 */ @PostMapping("/insert") public BookEntity insertBook(BookEntity bookEntity) { bookDao.save(bookEntity); return bookEntity; } /** * 删除 */ @DeleteMapping("/delete/{id}") public BookEntity deleteById(@PathVariable String id) { BookEntity bookEntity = bookDao.findOne(id); bookDao.delete(id); return bookEntity; } /** * 修改 * @param bookEntity * @return */ @PutMapping("/update") public BookEntity updateBook(BookEntity bookEntity) { bookDao.save(bookEntity); return bookEntity; }
简单演示ElasticsearchTemplate模板类的使用
/** * @Auther: ZhangShenao * @Date: 2018/8/24 10:46 * @Description:使用ElasticsearchTemplate模板类操作ElasticSearch */ @RestController @RequestMapping("/book/template") public class BookControllerWithTemplate { @Autowired ElasticsearchTemplate elasticsearchTemplate; /** * 查询所有 */ @GetMapping("/find_all") public List<Map<String, Object>> findAll() { Client client = elasticsearchTemplate.getClient(); SearchRequestBuilder srb = client.prepareSearch("product").setTypes("book"); SearchResponse sr = srb.setQuery(QueryBuilders.matchAllQuery()).execute().actionGet(); // 查询所有 SearchHits hits = sr.getHits(); List<Map<String, Object>> datas = new ArrayList<>(); for (SearchHit hit : hits) { Map<String, Object> source = hit.getSource(); datas.add(source); System.out.println(hit.getSourceAsString()); } return datas; } }
总结
综上,可以看到,使用Spring Data框架或者ElasticsearchTemplate可以十分方便的操作ElasticSearch,简化了原生Restful API的复杂性。