• 引入依赖
- spring-boot-starter-data-elasticsearch
1. <dependency> 2. <groupId>org.springframework.boot</groupId> 3. <artifactId>spring-boot-starter-data-elasticsearch</artifactId> 4. </dependency>
• 配置Elasticsearch
解决netty启动冲突问题
1. @PostConstruct 2. public void init() { 3. // 解决netty启动冲突问题 4. // see Netty4Utils.setAvailableProcessors() 5. System.setProperty("es.set.netty.runtime.available.processors", "false"); 6. }
- cluster-name、cluster-nodes
1. # ElasticsearchProperties 2. spring.data.elasticsearch.cluster-name=nowcoder 3. spring.data.elasticsearch.cluster-nodes=127.0.0.1:9300
• Spring Data Elasticsearch
Elasticsearch有两种方式可以调用:
- ElasticsearchTemplate
案例:
1. 2. @Test 3. public void testSearchByTemplate() { 4. SearchQuery searchQuery = new NativeSearchQueryBuilder() 5. .withQuery(QueryBuilders.multiMatchQuery("互联网寒冬", "title", "content")) 6. .withSort(SortBuilders.fieldSort("type").order(SortOrder.DESC)) 7. .withSort(SortBuilders.fieldSort("score").order(SortOrder.DESC)) 8. .withSort(SortBuilders.fieldSort("createTime").order(SortOrder.DESC)) 9. .withPageable(PageRequest.of(0, 10)) 10. .withHighlightFields( 11. new HighlightBuilder.Field("title").preTags("<em>").postTags("</em>"), 12. new HighlightBuilder.Field("content").preTags("<em>").postTags("</em>") 13. ).build(); 14. 15. Page<DiscussPost> page = elasticTemplate.queryForPage(searchQuery, DiscussPost.class, new SearchResultMapper() { 16. @Override 17. public <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> aClass, Pageable pageable) { 18. SearchHits hits = response.getHits(); 19. if (hits.getTotalHits() <= 0) { 20. return null; 21. } 22. 23. List<DiscussPost> list = new ArrayList<>(); 24. for (SearchHit hit : hits) { 25. DiscussPost post = new DiscussPost(); 26. 27. String id = hit.getSourceAsMap().get("id").toString(); 28. post.setId(Integer.valueOf(id)); 29. 30. String userId = hit.getSourceAsMap().get("userId").toString(); 31. post.setUserId(Integer.valueOf(userId)); 32. 33. String title = hit.getSourceAsMap().get("title").toString(); 34. post.setTitle(title); 35. 36. String content = hit.getSourceAsMap().get("content").toString(); 37. post.setContent(content); 38. 39. String status = hit.getSourceAsMap().get("status").toString(); 40. post.setStatus(Integer.valueOf(status)); 41. 42. String createTime = hit.getSourceAsMap().get("createTime").toString(); 43. post.setCreateTime(new Date(Long.valueOf(createTime))); 44. 45. String commentCount = hit.getSourceAsMap().get("commentCount").toString(); 46. post.setCommentCount(Integer.valueOf(commentCount)); 47. 48. // 处理高亮显示的结果 49. HighlightField titleField = hit.getHighlightFields().get("title"); 50. if (titleField != null) { 51. post.setTitle(titleField.getFragments()[0].toString()); 52. } 53. 54. HighlightField contentField = hit.getHighlightFields().get("content"); 55. if (contentField != null) { 56. post.setContent(contentField.getFragments()[0].toString()); 57. } 58. 59. list.add(post); 60. } 61. 62. return new AggregatedPageImpl(list, pageable, 63. hits.getTotalHits(), response.getAggregations(), response.getScrollId(), hits.getMaxScore()); 64. } 65. }); 66. 67. System.out.println(page.getTotalElements()); 68. System.out.println(page.getTotalPages()); 69. System.out.println(page.getNumber()); 70. System.out.println(page.getSize()); 71. for (DiscussPost post : page) { 72. System.out.println(post); 73. } 74. }
- ElasticsearchRepository
首先写一个接口扩展 ElasticsearchRepository
1. @Repository 2. public interface DiscussPostRepository extends ElasticsearchRepository<DiscussPost, Integer> { 3. 4. }
这里我们可以直接调用相关接口实现增删改查的功能
案例:
1. @Autowired 2. private DiscussPostRepository discussRepository; 3. 4. @Test 5. public void testInsert() { 6. for(int i = 109; i <= 280; i++) 7. discussRepository.save(discussMapper.selectDiscussPostById(i)); 8. } 9. 10. @Test 11. public void testInsertList() { 12. discussRepository.saveAll(discussMapper.selectDiscussPosts(101, 0, 100, 0)); 13. discussRepository.saveAll(discussMapper.selectDiscussPosts(102, 0, 100, 0)); 14. discussRepository.saveAll(discussMapper.selectDiscussPosts(103, 0, 100, 0)); 15. discussRepository.saveAll(discussMapper.selectDiscussPosts(111, 0, 100, 0)); 16. discussRepository.saveAll(discussMapper.selectDiscussPosts(112, 0, 100, 0)); 17. discussRepository.saveAll(discussMapper.selectDiscussPosts(131, 0, 100, 0)); 18. discussRepository.saveAll(discussMapper.selectDiscussPosts(132, 0, 100, 0)); 19. discussRepository.saveAll(discussMapper.selectDiscussPosts(133, 0, 100, 0)); 20. discussRepository.saveAll(discussMapper.selectDiscussPosts(134, 0, 100, 0)); 21. } 22. 23. @Test 24. public void testUpdate() { 25. DiscussPost post = discussMapper.selectDiscussPostById(231); 26. post.setContent("我是新人,使劲灌水."); 27. discussRepository.save(post); 28. } 29. 30. @Test 31. public void testDelete() { 32. discussRepository.deleteById(319); 33. discussRepository.deleteById(320); 34. discussRepository.deleteById(321); 35. // discussRepository.deleteAll(); 36. } 37. 38. @Test 39. public void testSearchByRepository() { 40. SearchQuery searchQuery = new NativeSearchQueryBuilder() 41. .withQuery(QueryBuilders.multiMatchQuery("互联网寒冬", "title", "content")) 42. .withSort(SortBuilders.fieldSort("type").order(SortOrder.DESC)) 43. .withSort(SortBuilders.fieldSort("score").order(SortOrder.DESC)) 44. .withSort(SortBuilders.fieldSort("createTime").order(SortOrder.DESC)) 45. .withPageable(PageRequest.of(0, 10)) 46. .withHighlightFields( 47. new HighlightBuilder.Field("title").preTags("<em>").postTags("</em>"), 48. new HighlightBuilder.Field("content").preTags("<em>").postTags("</em>") 49. ).build(); 50. 51. // elasticTemplate.queryForPage(searchQuery, class, SearchResultMapper) 52. // 底层获取得到了高亮显示的值, 但是没有返回. 53. 54. Page<DiscussPost> page = discussRepository.search(searchQuery); 55. System.out.println(page.getTotalElements()); 56. System.out.println(page.getTotalPages()); 57. System.out.println(page.getNumber()); 58. System.out.println(page.getSize()); 59. for (DiscussPost post : page) { 60. System.out.println(post); 61. } 62. }