摘要: 原創(chuàng)出處 www.bysocket.com 「泥瓦匠BYSocket 」歡迎轉(zhuǎn)載强窖,保留摘要,謝謝游沿!
『 預(yù)見(jiàn)未來(lái)最好的方式就是親手創(chuàng)造未來(lái) - 《史蒂夫·喬布斯傳》 』
運(yùn)行環(huán)境:JDK 7 或 8饰抒,Maven 3.0+技術(shù)棧:SpringBoot 1.5+,ElasticSearch 2.3.2本文提綱一诀黍、ES 的使用場(chǎng)景二袋坑、運(yùn)行 springboot-elasticsearch 工程三、springboot-elasticsearch 工程代碼詳解
一眯勾、ES 的使用場(chǎng)景
簡(jiǎn)單說(shuō)枣宫,ElasticSearch(簡(jiǎn)稱 ES)是搜索引擎,是結(jié)構(gòu)化數(shù)據(jù)的分布式搜索引擎吃环。在《Elasticsearch 和插件 elasticsearch-head 安裝詳解》 ?和 《Elasticsearch 默認(rèn)配置 IK 及 Java AnalyzeRequestBuilder 使用》 我詳細(xì)的介紹了如何安裝也颤,初步使用了 IK 分詞器。這里郁轻,我主要講下 SpringBoot 工程中如何使用 ElasticSearch翅娶。ES 的使用場(chǎng)景大致分為兩塊1. 全文檢索。加上分詞(IK 是其中一個(gè))、拼音插件等可以成為強(qiáng)大的全文搜索引擎竭沫。2. 日志統(tǒng)計(jì)分析厂庇。可以實(shí)時(shí)動(dòng)態(tài)分析海量日志數(shù)據(jù)输吏。
二权旷、運(yùn)行 springboot-elasticsearch 工程
注意的是這里使用的是 ElasticSearch 2.3.2。是因?yàn)?a target="_blank" rel="nofollow">版本對(duì)應(yīng)關(guān)系:
Spring Boot Version (x) Spring Data Elasticsearch Version (y) Elasticsearch Version (z)
x <= 1.3.5 y <= 1.3.4 z <= 1.7.2* x >= 1.4.x 2.0.0 <=y < 5.0.0** 2.0.0 <= z < 5.0.0**
* - 只需要你修改下對(duì)應(yīng)的 pom 文件版本號(hào)
** - 下一個(gè) ES 的版本會(huì)有重大的更新
git clone 下載工程 springboot-elasticsearch 贯溅,項(xiàng)目地址見(jiàn) GitHub - https://github.com/JeffLi1993/springboot-learning-example拄氯。1. 后臺(tái)起守護(hù)線程啟動(dòng) Elasticsearch
cd elasticsearch-2.3.2/
./bin/elasticsearch -d
下面開(kāi)始運(yùn)行工程步驟(Quick Start):2. 項(xiàng)目結(jié)構(gòu)介紹
org.spring.springboot.controller - Controller 層
org.spring.springboot.repository - ES 數(shù)據(jù)操作層
org.spring.springboot.domain - 實(shí)體類
org.spring.springboot.service - ES 業(yè)務(wù)邏輯層
Application - 應(yīng)用啟動(dòng)類
application.properties - 應(yīng)用配置文件,應(yīng)用啟動(dòng)會(huì)自動(dòng)讀取配置
本地啟動(dòng)的 ES 它浅,就不需要改配置文件了译柏。如果連測(cè)試 ES 服務(wù)地址,需要修改相應(yīng)配置3.編譯工程在項(xiàng)目根目錄 springboot-elasticsearch姐霍,運(yùn)行 maven 指令:
mvn clean install
4.運(yùn)行工程右鍵運(yùn)行 Application 應(yīng)用啟動(dòng)類(位置:/springboot-learning-example/springboot-elasticsearch/src/main/java/org/spring/springboot/Application.java)的 main 函數(shù)鄙麦,這樣就成功啟動(dòng)了 springboot-elasticsearch 案例。用 Postman 工具新增兩個(gè)城市新增城市信息
POST http://127.0.0.1:8080/api/city
{
"id":"1",
"provinceid":"1",
"cityname":"溫嶺",
"description":"溫嶺是個(gè)好城市"
}
POST http://127.0.0.1:8080/api/city
{
"id":"2",
"provinceid":"2",
"cityname":"溫州",
"description":"溫州是個(gè)熱城市"
}
可以打開(kāi) ES 可視化工具 head 插件:http://localhost:9200/_plugin/head/:(如果不知道怎么安裝镊折,請(qǐng)查閱 《Elasticsearch 和插件 elasticsearch-head 安裝詳解》 胯府。)在「數(shù)據(jù)瀏覽」tab,可以查閱到 ES 中數(shù)據(jù)是否被插入恨胚,插入后的數(shù)據(jù)格式如下:
{
"_index": "cityindex",
"_type": "city",
"_id": "1",
"_version": 1,
"_score": 1,
"_source": {
"id": 1,
"provinceid": 1,
"cityname": "溫嶺",
"description": "溫嶺是個(gè)好城市"
}
}
下面驗(yàn)證下權(quán)重分查詢搜索接口的實(shí)現(xiàn):GET http://localhost:8080/api/city/search?pageNumber=0&pageSize=10&searchContent=溫嶺數(shù)據(jù)是會(huì)出現(xiàn)
[
{
"id": 1,
"provinceid": 1,
"cityname": "溫嶺",
"description": "溫嶺是個(gè)好城市"
},
{
"id": 2,
"provinceid": 2,
"cityname": "溫州",
"description": "溫州是個(gè)熱城市"
}
]
從啟動(dòng)后臺(tái) Console 可以看出骂因,打印出來(lái)對(duì)應(yīng)的 DSL 語(yǔ)句:
{
"function_score" : {
"functions" : [ {
"filter" : {
"bool" : {
"should" : {
"match" : {
"cityname" : {
"query" : "溫嶺",
"type" : "boolean"
}
}
}
}
},
"weight" : 1000.0
}, {
"filter" : {
"bool" : {
"should" : {
"match" : {
"description" : {
"query" : "溫嶺",
"type" : "boolean"
}
}
}
}
},
"weight" : 100.0
} ]
}
}
為什么會(huì)出現(xiàn) 溫州 城市呢?因?yàn)?function score query 權(quán)重分查詢赃泡,無(wú)相關(guān)的數(shù)據(jù)默認(rèn)分值為 1寒波。如果想除去,設(shè)置一個(gè) setMinScore 分值即可升熊。
三俄烁、springboot-elasticsearch 工程代碼詳解
具體代碼見(jiàn)GitHub-https://github.com/JeffLi1993/springboot-learning-example
1.pom.xml 依賴
這里依賴的 spring-boot-starter-data-elasticsearch 版本是 1.5.1.RELEASE,對(duì)應(yīng)的 spring-data-elasticsearch 版本是 2.1.0.RELEASE级野。后面數(shù)據(jù)操作層都是通過(guò)該 spring-data-elasticsearch 提供的接口實(shí)現(xiàn)页屠。操作對(duì)應(yīng)官方文檔:http://docs.spring.io/spring-data/elasticsearch/docs/2.1.0.RELEASE/reference/html/。
2. application.properties 配置 ES 地址
# ES
spring.data.elasticsearch.repositories.enabled = true
spring.data.elasticsearch.cluster-nodes = 127.0.0.1:9300
默認(rèn) 9300 是 Java 客戶端的端口勺阐。9200 是支持 Restful HTTP 的接口卷中。更多配置:
spring.data.elasticsearch.cluster-name Elasticsearch 集群名。(默認(rèn)值: elasticsearch)
spring.data.elasticsearch.cluster-nodes 集群節(jié)點(diǎn)地址列表渊抽,用逗號(hào)分隔蟆豫。如果沒(méi)有指定,就啟動(dòng)一個(gè)客戶端節(jié)點(diǎn)懒闷。
spring.data.elasticsearch.propertie 用來(lái)配置客戶端的額外屬性十减。
spring.data.elasticsearch.repositories.enabled 開(kāi)啟 Elasticsearch 倉(cāng)庫(kù)栈幸。(默認(rèn)值:true。)
3. ES 數(shù)據(jù)操作層
@Repository
public interface CityRepository extends ElasticsearchRepository {
}
接口只要繼承 ElasticsearchRepository 類即可帮辟。默認(rèn)會(huì)提供很多實(shí)現(xiàn)速址,比如 CRUD 和搜索相關(guān)的實(shí)現(xiàn)。
4. 實(shí)體類
@Document(indexName = "cityindex", type = "city")
public class City implements Serializable{
private static final long serialVersionUID = -1L;
/**
* 城市編號(hào)
*/
private Long id;
/**
* 省份編號(hào)
*/
private Long provinceid;
/**
* 城市名稱
*/
private String cityname;
/**
* 描述
*/
private String description;
}
注意index 配置必須是全部小寫(xiě)由驹,不然會(huì)暴異常芍锚。org.elasticsearch.indices.InvalidIndexNameException: Invalid index name [cityIndex], must be lowercase
5. ES 業(yè)務(wù)邏輯層
/**
* 城市 ES 業(yè)務(wù)邏輯實(shí)現(xiàn)類
*
* Created by bysocket on 07/02/2017.
*/
@Service
public class CityESServiceImpl implements CityService {
private static final Logger LOGGER = LoggerFactory.getLogger(CityESServiceImpl.class);
@Autowired
CityRepository cityRepository;
@Override
public Long saveCity(City city) {
City cityResult = cityRepository.save(city);
return cityResult.getId();
}
@Override
public List searchCity(Integer pageNumber,
Integer pageSize,
String searchContent) {
// 分頁(yè)參數(shù)
Pageable pageable = new PageRequest(pageNumber, pageSize);
// Function Score Query
FunctionScoreQueryBuilder functionScoreQueryBuilder = QueryBuilders.functionScoreQuery()
.add(QueryBuilders.boolQuery().should(QueryBuilders.matchQuery("cityname", searchContent)),
ScoreFunctionBuilders.weightFactorFunction(1000))
.add(QueryBuilders.boolQuery().should(QueryBuilders.matchQuery("description", searchContent)),
ScoreFunctionBuilders.weightFactorFunction(100));
// 創(chuàng)建搜索 DSL 查詢
SearchQuery searchQuery = new NativeSearchQueryBuilder()
.withPageable(pageable)
.withQuery(functionScoreQueryBuilder).build();
LOGGER.info("\n searchCity(): searchContent [" + searchContent + "] \n DSL? = \n " + searchQuery.getQuery().toString());
Page searchPageResults = cityRepository.search(searchQuery);
return searchPageResults.getContent();
}
}
保存邏輯很簡(jiǎn)單。分頁(yè) function score query 搜索邏輯如下:先創(chuàng)建分頁(yè)參數(shù)蔓榄,然后用 FunctionScoreQueryBuilder 定義 Function Score Query并炮,并設(shè)置對(duì)應(yīng)字段的權(quán)重分值。城市名稱 1000 分甥郑,description 100 分逃魄。然后創(chuàng)建該搜索的 DSL 查詢,并打印出來(lái)澜搅。
四伍俘、小結(jié)
實(shí)際場(chǎng)景還會(huì)很復(fù)雜。這里只是點(diǎn)睛之筆勉躺,后續(xù)大家優(yōu)化或者更改下 DSL 語(yǔ)句就可以完成自己想要的搜索規(guī)則癌瘾。
推薦:《Spring Boot 整合 Dubbo/ZooKeeper 詳解 SOA 案例》上一篇:《Spring Boot 整合 Mybatis Annotation 注解案例》
歡迎掃一掃我的公眾號(hào)關(guān)注 — 及時(shí)得到博客訂閱哦!
—https://github.com/JeffLi1993—