指令碼生命週期流程圖
阿新 • • 發佈:2021-02-06
技術標籤:javaspring bootspringelasticsearchbootstrap
跟著《牛客高薪專案求職課》的 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 渲染即可實現高亮顯示的樣式
參考:springboot整合Elasticsearch7.6實現簡單查詢及高亮分詞查詢
可能遇到的問題:
問題一:
如果遇到了下面這個問題,多半是因為注入錯了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)} 問題二 DiscussPost.createTime is annotated with FieldType.Date but has no DateFormat defined 問題三: ElasticsearchStatusException[Elasticsearch exception [type=invalid_index_name_exception, reason=Invalid index name [discussPost], must be lowercase]] 參考:springboot整合Elasticsearch7.6實現簡單查詢及高亮分詞查詢