ElasticSearch找不到SearchResultMapper类
跟着《牛客高薪项目求职课》的2019.6版视频做项目,做到ElasticSearch这一节的时候,发现有个SearchResultMapper类一直导入不进去,尝试了各种办法仍然没有用,后面觉得应该是这个类已经被删除了,所以照着网上的教程换了一种方式来实现高亮显示。
使用的环境是:
spring boot 2.3.4
elasticsearch 7.6.2
导入了下面这个依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> <version>2.3.4.RELEASE</version> </dependency>
遇到的情况
下面这个SearchResultMapper类一直导入不进去,就算直接把老师的import语句加到头文件中也没用,一开始以为是我的es 包版本导错了,但是尝试了很多个版本的包依赖都没有用,后面直接放弃这种方法了。
解决方法如下:
application.properties配置类中对Elasticsearch的配置已经过期了,所以应该使用配置类的方式来注入bean
改用配置类的方式来注入Bean, 配置文件如下
@Configuration public class EsConfig{ @Value("${elasticSearch.url}") private String esUrl; //localhost:9200 写在配置文件中就可以了 @Bean RestHighLevelClient client() { ClientConfiguration clientConfiguration = ClientConfiguration.builder() .connectedTo(esUrl)//elasticsearch地址 .build(); return RestClients.create(clientConfiguration).rest(); } }
我的实体类如下
1 @Document(indexName = "discusspost", type = "_doc", shards = 6, replicas = 3) 2 public class DiscussPost { 3 4 @Id 5 private int id; 6 7 @Field(type = FieldType.Integer) 8 private int userId; 9 10 @Field(type = FieldType.Text, analyzer = "ik_max_word", searchAnalyzer = "ik_smart") 11 private String title; 12 13 @Field(type = FieldType.Text, analyzer = "ik_max_word", searchAnalyzer = "ik_smart") 14 private String content; 15 16 @Field(type = FieldType.Integer) 17 private int type; 18 19 @Field(type = FieldType.Integer) 20 private int status; 21 22 @Field(type = FieldType.Date, format=DateFormat.date_optional_time) 23 private Date createTime; 24 25 @Field(type = FieldType.Integer) 26 private int commentCount; 27 28 @Field(type = FieldType.Double) 29 private double score; 30 31 // 下面省略了get和set方法,也省略了toString()方法,自行补充 32 33 }
测试类如下
1 @RunWith(SpringRunner.class) 2 @SpringBootTest 3 @ContextConfiguration(classes = CommunityApplication.class) 4 public class ElasticSearchTests { 5 6 @Autowired 7 private DiscussPostMapper discussPostMapper; 8 9 @Autowired 10 private ElasticsearchRestTemplate elasticsearchRestTemplate; // 注意不要注入ElasticsearchTemplate 11 12 @Test 13 public void testSearchByTemplate(){ 14 NativeSearchQuery searchQuery = new NativeSearchQueryBuilder() 15 .withQuery(QueryBuilders.multiMatchQuery("互联网寒冬", "title", "content")) 16 .withSort(SortBuilders.fieldSort("type").order(SortOrder.DESC)) 17 .withSort(SortBuilders.fieldSort("score").order(SortOrder.DESC)) 18 .withSort(SortBuilders.fieldSort("createTime").order(SortOrder.DESC)) 19 .withPageable(PageRequest.of(0, 10)) 20 .withHighlightFields( 21 new HighlightBuilder.Field("title").preTags("<em>").postTags("</em>"), 22 new HighlightBuilder.Field("content").preTags("<em>").postTags("</em>") 23 ).build(); 24 //elasticsearchTemplate.queryForPage() 25 //elasticsearchRestTemplate.queryForPage(searchQuery, DiscussPost.class, new SearchRe) 26 27 SearchHits<DiscussPost> search = elasticsearchRestTemplate.search(searchQuery, DiscussPost.class); 28 // 得到查询结果返回的内容 29 List<SearchHit<DiscussPost>> searchHits = search.getSearchHits(); 30 // 设置一个需要返回的实体类集合 31 List<DiscussPost> discussPosts = new ArrayList<>(); 32 // 遍历返回的内容进行处理 33 for(SearchHit<DiscussPost> searchHit : searchHits){ 34 // 高亮的内容 35 Map<String, List<String>> highLightFields = searchHit.getHighlightFields(); 36 // 将高亮的内容填充到content中 37 searchHit.getContent().setTitle(highLightFields.get("title") == null ? searchHit.getContent().getTitle() : highLightFields.get("title").get(0)); 38 searchHit.getContent().setTitle(highLightFields.get("content") == null ? searchHit.getContent().getContent() : highLightFields.get("content").get(0)); 39 // 放到实体类中 40 discussPosts.add(searchHit.getContent()); 41 } 42 System.out.println(discussPosts.size()); 43 for(DiscussPost discussPost : discussPosts){ 44 System.out.println(discussPost); 45 } 46 } 47 48 }
运行这个测试方法, 得到了预期的结果, 在搜索的关键词“寒冬” 和 ”互联网“ 前后都加上了<em></em>标签,通过css 渲染即可实现高亮显示的样式
如果遇到了下面这个问题,多半是因为注入错了template, 应该注入ElasticsearchRestTemplate,而非ElasticsearchTemplate, 因为在 application.properties 这个配置文件中ElasticsearchTemplate的配置已经过期失效了,所以注入不进去,而我们使用配置类注入的是ElasticsearchRestTemplate,所以在spring容器中找不到ElasticsearchTemplate, 所以报错
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.nowcoder.work.community.ElasticSearchTests': Unsatisfied dependency expressed through field 'elasticsearchRestTemplate'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.data.elasticsearch.core.ElasticsearchTemplate' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
问题二
下面是这个仿牛客网项目的github地址,有需要的同学可以对照上面的代码完成这个搜索功能。