版本
8.4
安裝
windows本地安裝,直接下載zip包解壓即可
windows安裝官方教程
啟動
.\bin\elasticsearch.bat
elasticsearch本地就跑起來了
配置
主配置文件在config下的elasticsearch.yml
elasticsearch默認(rèn)是要校驗身份的,可以暫時去掉xpack.security.enabled修改為false
# Enable security features
xpack.security.enabled: false
配置可跨域(否則跨域不可訪問)
http.cors.enabled: true
http.cors.allow-origin: "*"
http.host: 0.0.0.0

重啟之后既可以開始使用了,簡單測試一下是否正常
$ curl localhost:9200

elasticsearch本地就搭建好了
客戶端
就像mysql有navicat等客戶端,用起來方便又直觀,elasticsearch也有一個勉強可用的客戶端
elasticsearch-head,是一個前端的代碼,下載下來,運行也很簡單: npm install安裝依賴,npm run start運行,打開界面即可http://localhost:9100/

但從實際效果上看,客戶端提供的功能非常少,也不適合初學(xué)者學(xué)習(xí)
概念
Elasticsearch可以看做一個便于搜索的數(shù)據(jù)庫,相比傳統(tǒng)關(guān)系型數(shù)據(jù)庫如下
Mysql ‐> Databases ‐> Tables ‐> Rows ‐> Columns
Elasticsearch ‐> Indices ‐> Types ‐> Documents ‐> Fields
Elasticsearch 8 已經(jīng)刪除了Types,所以現(xiàn)在的層級應(yīng)該是
Elasticsearch ‐> Indices ‐> Documents ‐> Fields
Index
索引,相當(dāng)于mysql中的一個數(shù)據(jù)表(原來有type時它相當(dāng)于數(shù)據(jù)庫,type相當(dāng)于數(shù)據(jù)表,現(xiàn)在es8取消了type,index當(dāng)做一個數(shù)據(jù)表來理解方便一點)
Documents
一條存儲的數(shù)據(jù),相當(dāng)于mysql的一條數(shù)據(jù)
Fields
字段,類似mysql的子墩
API
Elasticsearch牛在封裝了Lucene,提供了強大的搜索功能,同時對外暴露Restful Api使其易于對接,接下來就通過調(diào)用api來實現(xiàn)一個小功能:
存儲一個網(wǎng)站的文章,并可以通過標(biāo)題和內(nèi)容智能檢索
第一步,創(chuàng)建文章索引
就好比在mysql中創(chuàng)建一個文章表article,包含三個字段id,title,content
curl --location --request PUT 'http://127.0.0.1:9200/article' \
--header 'Content-Type: application/json' \
--data-raw '{
"mappings": {
"properties": {
"id": {
"type": "long",
"index": false
},
"title": {
"type": "text",
"analyzer": "standard"
},
"content": {
"type": "text",
"analyzer": "standard"
}
}
}
}'
關(guān)于索引的文檔,可以參考Index APIs
第二步,添加幾個測試文章
curl --location --request POST 'http://127.0.0.1:9200/article/_doc/1' \
--header 'Content-Type: application/json' \
--data-raw '{
"id": 1,
"title": "小李飛刀",
"content": "小李飛刀,例無虛發(fā)"
}'
其中url上article代表索引名,_doc是默認(rèn),1代表id,如果沒有則自動生成,請求體即文章的標(biāo)題和內(nèi)容
多增加幾個文章進行測試

關(guān)于文檔的文檔,可以參考Document APIs
第三步,檢索
測試數(shù)據(jù)準(zhǔn)備好了,接下來進行搜索測試,我們搜索"刀",并希望所有帶"刀"字樣的都搜出來,相當(dāng)于sql的
WHERE (title like '%刀%' OR content like '%刀%')
寫法如下,使用布爾過濾器
curl --location --request GET 'http://localhost:9200/article/_search' \
--header 'Content-Type: application/json' \
--data-raw '{
"query": {
"bool": {
"should": [
{ "match": { "title": "刀" }},
{ "match": { "content": "刀" }}
]
}
}
}'
最終輸出結(jié)果如下

可以看到實現(xiàn)了我們的需求,帶“刀”的數(shù)據(jù)都被查了出來
再搜索一下"刀劍"

可以看到相關(guān)的都被查出,這種查詢在mysql是做不到的
這種搜索查詢的語法是ES自己指定的,可以支持很多復(fù)雜的查詢方式,而且有一個很不錯的中文文檔,文檔可能有些過期,但大部分還好,并且人性化的對照了mysql的場景
整合springboot
如果想簡單粗暴的代碼調(diào)用es,其實使用HttpClient也可以,畢竟都是http接口,道理很簡單,但寫的代碼肯定很費勁
為了方便用戶使用,es肯定是要提供sdk的,即
elasticsearch-rest-high-level-client,專門針對es的客戶端,使用起來肯定更方便為了使用更加方便,spring在elasticsearch-client基礎(chǔ)上再次封裝出了
spring-data-elasticsearch,進一步的封裝使spring用戶調(diào)用es非常方便
spring每個階段會根據(jù)spring的當(dāng)前版本以及es的版本在不同時期適配不同的依賴包,這就導(dǎo)致每個spring-data-elasticsearch版本肯定會有一個適用的spring版本及es版本,當(dāng)前的關(guān)系如下

很不幸,當(dāng)前好像并沒有適配es8的版本,且我自己用的springboot版本為2.3.x,所以只能嘗試使用4.0.x的spring-data-elasticsearch,考慮到這種牛逼項目都有低版本適配,問題應(yīng)該也不大
引入依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
配置Elasticsearch
主要是配置服務(wù)器地址,超時時間什么的,創(chuàng)建一個RestHighLevelClient客戶端的bean
@Configuration
public class ElasticsearchClientConfig extends AbstractElasticsearchConfiguration {
// 地址
@Value("${spring.data.elasticsearch.host}")
private String host;
// 端口
@Value("${spring.data.elasticsearch.port}")
private String port;
@Override
@Bean
public RestHighLevelClient elasticsearchClient() {
final ClientConfiguration clientConfiguration = ClientConfiguration.builder()
.connectedTo(host + ":" + port)
.build();
return RestClients.create(clientConfiguration).rest();
}
}
到此spring的es配置結(jié)束,接下來就是增刪查改,用過jpa的會發(fā)現(xiàn)基本一個套路
定義實體,映射到索引
創(chuàng)建一個實體Book并映射到es的索引book
@Data
@Document(indexName = "book",createIndex = true) // 映射book索引
public class Book {
// 主鍵標(biāo)識
@Id
@Field(type = FieldType.Long)
private Long id;
@Field(analyzer="standard")
private String title;
@Field(analyzer="standard")
private String content;
}
定義倉庫
public interface BookRepositoryImpl extends ElasticsearchRepository<Book, Long> {
List<Book> findByTitleOrContent(String title, String content);
}
這個倉庫的接口定義好之后,就可以通過spring注入,注入對象默認(rèn)包含方法
- save 保存,新增/修改
- findAll 查詢,帶分頁
- delete 刪除
- 等等
也可以自己定義方法,主要有兩種方式
一、直接從方法名稱派生查詢
例如上面的findByTitleOrContent就會自動轉(zhuǎn)化為根據(jù)標(biāo)題或內(nèi)容查詢
二、使用@Query注解自定義的查詢
例如
interface BookRepository extends ElasticsearchRepository<Book, String> {
@Query("{\"match\": {\"name\": {\"query\": \"?0\"}}}")
Page<Book> findByName(String name,Pageable pageable);
}
使用過jpa應(yīng)該再熟悉不過了,功能十分強大,可以參考官方文檔
使用倉庫
這就非常簡單了,寫個小例子
@Autowired
private BookRepository bookRepository;
public void test() {
Book book = new Book();
book.setId(1L);
book.setTitle("雪中悍刀行");
book.setContent("你是我的白月光,我是你的小砒霜");
// 新增文檔
bookRepository.save(book);
// 查詢所有
Iterable<Book> all = bookRepository.findAll();
for (book po : all) {
}
// 通過標(biāo)題或內(nèi)容查詢帶"刀"的文檔
List<Book> hits = bookRepository.findByTitleOrContent("刀", "刀");
}
修改版本不兼容問題
跑了一下還出出問題,報錯type不能為null,原因是es8已取消type,而我們低版本客戶端還是會校驗type必須存在,導(dǎo)致運行出錯,報錯點如下

修改辦法:
沒找到太好的解決辦法,只是粗暴的重寫了DocWriteResponse類
