SpringBoot集成elasticsearch使用圖文詳解
前言
此文適合了解了es相關(guān)概念以及基礎(chǔ)知識(shí)的同學(xué)閱讀
elasticsearch簡介
Elasticsearch是一個(gè)基于Lucene的搜索服務(wù)器。它提供了一個(gè)分布式多用戶能力的全文搜索引擎,基于RESTful風(fēng)格的http接口。
簡單來說,es主要是用來做搜索的,比如像商城網(wǎng)站中(商品、店鋪……)的搜索、小說網(wǎng)站中(書名、作者……)的搜索。
我們要知道,任何一門新的技術(shù)、框架、中間件出來肯定是為了解決一些問題。es的誕生就是為了在Lucene的基礎(chǔ)上更好的幫助我們解決傳統(tǒng)搜索的問題。
最原始、傳統(tǒng)的搜索功能都是基于db表的模糊查詢,這樣做有很大的局限性
- 多維度查詢實(shí)現(xiàn)復(fù)雜:現(xiàn)在的業(yè)務(wù)場景一般都是單輸入框、多維度搜索。舉個(gè)例子,你在電商網(wǎng)站的搜索框中,既能查詢商品、也能查詢店鋪?;蛘卟樵兤放?。這種業(yè)務(wù)場景下如果用傳統(tǒng)的db模糊查詢?nèi)?shí)現(xiàn),要么wehre語句后面多加好幾個(gè)條件,中間用or隔開,要么新增擴(kuò)展字段,將:商品名稱、店鋪名稱、品牌名稱等信息存到一個(gè)字段中,然后模糊查詢該字段。不論用哪種方式,對查詢性能以及代碼可讀性來講都是難以接受的。
- 查詢速度受數(shù)據(jù)限制:雖然模糊查詢寫的規(guī)范點(diǎn)也能走索引查詢,但是當(dāng)數(shù)據(jù)量起來之后,無可避免的會(huì)降低速度(索引也不是萬能的)。
es幫我們解決了上面的問題,它作為一個(gè)專業(yè)搜索的中間件,對于查詢搜索方面肯定跟redis做緩存一樣,完全沒問題。
elasticsearch使用
這里介紹SpringBoot如何集成es來使用。像目前主流的一些開源中間件技術(shù),Spring家族都幫我們集成進(jìn)去了。使用起來很方便
環(huán)境安裝
系統(tǒng):windows 10
下載好對應(yīng)的windows版本,解壓到任意工作目錄,es的安裝非常方便,解壓即用。

剛下載的es默認(rèn)的分詞器只能分解英文,對于中文不太友好。所以我們需要為es下載安裝IK分詞器
IK分詞器下載:
Ik分詞器下載地址,分詞器下載跟es版本對應(yīng)的就行。下載好后解壓zip包

在你下載的es安裝路徑下的plugins文件夾下創(chuàng)建一個(gè)ik的文件夾,然后將上面解壓出來的分詞器內(nèi)容復(fù)制到創(chuàng)建的ik文件夾下面。下面圖ik分詞器官方安裝說明

效果如下

ik分詞器的安裝就完成了,而后回答es根目錄下的bin目錄里,雙擊啟動(dòng)es

當(dāng)es正常啟動(dòng),且啟動(dòng)過程出現(xiàn)下面情況時(shí),說明ik分詞器已經(jīng)正常安裝好可以使用了

代碼演示
1、新建springboot項(xiàng)目,引入依賴
<!--springboot幫我們自動(dòng)集成了es,所以只需要引入下面這一個(gè)依賴即可-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
RestHighLevelClient配置
@Configuration
public class EsConfig {
@Bean
public RestHighLevelClient highLevelClient(){
final ClientConfiguration clientConfiguration = ClientConfiguration.builder()
.connectedTo("localhost:9200")
.build();
return RestClients.create(clientConfiguration).rest();
}
}2、在你的數(shù)據(jù)庫實(shí)體類里每個(gè)字段加上相應(yīng)的注解即可(跟Jpa一樣)
@Data
@Document(indexName = "book")
//es默認(rèn)會(huì)自動(dòng)創(chuàng)建索引,你可以把document理解為數(shù)據(jù)庫中的行,index理解為數(shù)據(jù)庫中的表,以前在index和document之間還有個(gè)type對應(yīng)數(shù)據(jù)庫中的表概念。后面es7之后將type去掉了,所以這里就簡單把index當(dāng)作一個(gè)表的概念去理解
public class Book {
@Id
@Field(type = FieldType.Long)//type表示存到es當(dāng)中的數(shù)據(jù)類型
private Long id;
@Field(type = FieldType.Text,analyzer = "ik-max-word")
private String bookName;//analyzer 表示選擇分詞器
@Field(type = FieldType.Text,analyzer = "ik-max-word")
private String bookDesc;
@Field(type = FieldType.Text)
private String type;
@Field(type = FieldType.Integer)
private Integer status;
@Field(analyzer = "ik-max-word")
private String author;
@Field(type = FieldType.Text)
private String tag;
@Field(type = FieldType.Date,format = DateFormat.basic_date_time)
private LocalDateTime createTime;
@Field(type = FieldType.Text)
private String createBy;
@Field(type = FieldType.Date,format = DateFormat.basic_date_time)
private LocalDateTime updateTime;
}
由于spring官方對es的高度封裝,我們已經(jīng)可以做到像操作數(shù)據(jù)庫一樣操作es了
以上面的Book對象舉例,創(chuàng)建接口EsBooksRepository,繼承Spring封裝的ElasticsearchRepository,ElasticsearchRepository提供了一些簡單的操作es方法
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package org.springframework.data.elasticsearch.repository;
import org.elasticsearch.index.query.QueryBuilder;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.query.Query;
import org.springframework.data.repository.NoRepositoryBean;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.lang.Nullable;
@NoRepositoryBean
public interface ElasticsearchRepository<T, ID> extends PagingAndSortingRepository<T, ID> {
/** @deprecated */
@Deprecated
default <S extends T> S index(S entity) {
return this.save(entity);
}
/** @deprecated */
@Deprecated
<S extends T> S indexWithoutRefresh(S entity);
/** @deprecated */
@Deprecated
Iterable<T> search(QueryBuilder query);
/** @deprecated */
@Deprecated
Page<T> search(QueryBuilder query, Pageable pageable);
/** @deprecated */
Page<T> search(Query searchQuery);
Page<T> searchSimilar(T entity, @Nullable String[] fields, Pageable pageable);
/** @deprecated */
@Deprecated
void refresh();
}
到這一步,就已經(jīng)可以簡單的使用了??梢栽谄渌胤街苯訉?chuàng)建的EsBooksRepository這個(gè)接口注入使用。比如我測試方便,直接在controller里使用

保存或者更新時(shí),先存db后操作es。


普通查詢
上面說到集成了spring-boot-starter-data-elasticsearch后,用法上跟Jpa一樣,我們可以在自己創(chuàng)建的EsBooksRepository里自定義根據(jù)方法名查詢對應(yīng)的條件

簡單的查詢根據(jù)方法名定義就能實(shí)現(xiàn),比如說我需要查詢的是多條數(shù)據(jù),那我就選findBooksBy……,如果需要查詢1條就選findBookBy

findXXBy后面接條件,方法名定義了幾個(gè)條件,就需要傳幾個(gè)參數(shù)定義好調(diào)用的時(shí)候,直接將前端傳遞的搜索值所有參數(shù)塞一遍就好了
//這里定義了兩個(gè)查詢條件:書名和作者,直接將搜索值傳遞給定義好的方法就行 List<Book> booksByBookNameAndAuthor = esBookRepository.findBooksByBookNameOrAuthor(nameAndAuthor,nameAndAuthor);
測試結(jié)果:查詢條件值是“我的”,結(jié)果返回所有書名和作者名含有“我的”兩個(gè)字的book對象

高亮查詢
高亮查詢需要設(shè)置一些地方,下面是高亮查詢的簡單demo。
/**
* 書名、作者搜索
*/
@RequestMapping(method = RequestMethod.GET, value = {"/book/search" })
public RestResponse<List<Book>> search(@RequestParam String nameAndAuthor){
BoolQueryBuilder queryBuilder = new BoolQueryBuilder();
//匹配兩個(gè)高亮字段:書名、作者
queryBuilder.should(QueryBuilders.matchQuery("bookName",nameAndAuthor))
.should(QueryBuilders.matchQuery("author",nameAndAuthor));
//設(shè)置查詢高亮樣式preTags、postTags
//高亮查詢其實(shí)就是給相應(yīng)需要高亮顯示的字段加個(gè)自定義樣式
NativeSearchQuery query = new NativeSearchQueryBuilder()
.withQuery(queryBuilder)
.withHighlightFields(new HighlightBuilder.Field("bookName")
,new HighlightBuilder.Field("author"))
.withHighlightBuilder(new HighlightBuilder().preTags("<span style='color:red'>").postTags("</span>"))
.build();
SearchHits<Book> search = elasticsearchRestTemplate.search(query, Book.class);
List<SearchHit<Book>> searchHits = search.getSearchHits();
//查詢返回結(jié)果,將高亮字段重新賦值給相應(yīng)book對象,以便返回前端展示
List<Book> collect = searchHits.stream().map(
bookSearchHit -> {
Book content = bookSearchHit.getContent();
List<String> bookName = bookSearchHit.getHighlightField("bookName");
List<String> author = bookSearchHit.getHighlightField("author");
if (!CollectionUtils.isEmpty(bookName)){
content.setBookName(bookName.get(0));
}
if (!CollectionUtils.isEmpty(author)){
content.setAuthor(author.get(0));
}
return content;
}
).collect(Collectors.toList());
return RestResponse.success(collect);
}
結(jié)果:可以看到返回的數(shù)據(jù)中,“我的”這兩個(gè)字都添加了高亮樣式,放到前端html展示就是紅字字體

結(jié)束
以上就是springboot集成es后的一個(gè)簡單使用,spring封裝過后的spring-boot-starter-data-elasticsearch使用起來還是非常方便簡單的。
到此這篇關(guān)于SpringBoot集成elasticsearch使用的文章就介紹到這了,更多相關(guān)SpringBoot集成elasticsearch使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
tomcat connection-timeout連接超時(shí)源碼解析
這篇文章主要為大家介紹了tomcat connection-timeout連接超時(shí)源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-11-11
關(guān)于java.util.Random的實(shí)現(xiàn)原理詳解
Java實(shí)用工具類庫中的類java.util.Random提供了產(chǎn)生各種類型隨機(jī)數(shù)的方法,下面這篇文章主要給大家介紹了關(guān)于java.util.Random實(shí)現(xiàn)原理的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下。2017-08-08
Java代碼實(shí)現(xiàn)矩形覆蓋實(shí)例
這篇文章主要介紹了Java代碼實(shí)現(xiàn)矩形覆蓋實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,,需要的朋友可以參考下2019-06-06
Springboot使用ResponseBody漢字返回問號(hào)問題
這篇文章主要介紹了Springboot使用ResponseBody漢字返回問號(hào)問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-06-06

