ElasticSearch的介紹及使用
1.ElasticSearch
簡介 : 是一個基於Lucene的搜尋伺服器。它提供了一個分散式多使用者能力的全文搜尋引擎,基於RESTful web介面。Elasticsearch是用Java開發的,並作為Apache許可條款下的開放原始碼釋出,是當前流行的企業級搜尋引擎。
Elasticsearch官網:https://www.elastic.co/cn/products/elasticsearch
特點:
- 分散式,無需人工搭建叢集(solr就需要人為配置,使用Zookeeper作為註冊中心)
- Restful風格,一切API都遵循Rest原則,容易上手
- 近實時搜尋,資料更新在Elasticsearch中幾乎是完全同步的。
版本 : 目前Elasticsearch最新的版本是6.4.1,我們使用這個版本6.2.4
需要JDK1.8及以上
2.瞭解搜尋技術
2.1. 搜尋引擎的種類
搜尋引擎按照功能通常分為垂直搜尋和綜合搜尋。
1、垂直搜尋是指專門針對某一類資訊進行搜尋。
例如:會搜網 主要做商務搜尋的,並且提供商務資訊。除此之外還有愛看圖示網、職友集等。
2、綜合搜尋是指對眾多資訊進行綜合性的搜尋。
例如:百度、谷歌、必應、搜狗、360搜尋等。
2.2 倒排索引
以我的理解就是:我們對資料庫原始的資料根據字或詞進行索引,建立倒排索引資料區域,記錄字或詞在文件中出現位置(id列表)。
使用者有查詢需求時,先訪問倒排索引資料區域(下圖),得出文件id列表後,通過文件id即可快速,準確的通過上圖找到具體的文件內容。
3.Elasticsearch安裝
3.1.安裝和配置
3.1.1 下載
下載地址:https://www.elastic.co/downloads/past-releases
3.2.2 安裝
elasticsearch無需安裝,解壓即用。雙擊執行
可以看到綁定了兩個埠:
- 9300:java程式訪問的埠
- 9200:瀏覽器、postman訪問介面
我們在瀏覽器中訪問:http://127.0.0.1:9200
3.4.安裝Head外掛
3.4.1.什麼是Head
ealsticsearch只是後端提供各種api,那麼怎麼直觀的使用它呢?elasticsearch-head將是一款專門針對於elasticsearch的客戶端工具
elasticsearch-head配置包,下載地址:https://github.com/mobz/elasticsearch-head
3.4.2.安裝
- es5以上版本安裝head需要安裝node和grunt
第一步:從地址:https://nodejs.org/en/download/ 下載相應系統的msi,雙擊安裝。
第二步:安裝完成用cmd進入安裝目錄執行 node -v可檢視版本號
第三步:執行 npm install -g grunt-cli 安裝grunt ,安裝完成後執行grunt -version檢視是否安裝成功,會顯示安裝的版本號
第四步:進入E:\environment2\elasticsearch-head-master資料夾,執行npm install命令
第五步:執行head外掛,下面命令二選一
- 命令一:npm run start
- 命令二:grunt server
第六步:訪問9100埠
3.4.3.配置執行
第一步:進入es安裝目錄下的config目錄,修改elasticsearch.yml檔案.在檔案的末尾加入以下程式碼
http.cors.enabled: true
http.cors.allow-origin: "*"
node.master: true
node.data: true
然後去掉network.host: 192.168.0.1的註釋並改為network.host: 0.0.0.0,去掉cluster.name;node.name;http.port的註釋(也就是去掉#)
第二步:雙擊elasticsearch.bat重啟es
第三步:在https://github.com/mobz/elasticsearch-head中下載head外掛,選擇下載zip
第四步:解壓到指定資料夾下,D:\environment\elasticsearch-head-master 進入該資料夾,修改D:\environment\elasticsearch-head-master\Gruntfile.js 在對應的位置加上hostname:’*’、
第五步:在D:\environment\elasticsearch-head-master 下執行npm install 安裝完成後執行grunt server 或者npm run start 執行head外掛,如果不成功重新安裝grunt。成功如下
4.入門案例(整合Springboot)
4.1 pom匯入依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
4.2 application.yml檔案配置
spring:
data:
elasticsearch:
cluster-name: my-application
cluster-nodes: 127.0.0.1:9300
4.3.索引操作
- 建立索引和對映
SpringBoot-data-elasticsearch提供了面向物件的方式操作elasticsearch業務:將商品的資訊存入elasticsearch,並且執行搜尋操作
實體類:
public class Item {
private Long id;
private String title; //標題
private String category;// 分類
private Double price; // 價格
private String images; // 圖片地址
}
對映—註解:
Spring Data通過註解來宣告欄位的對映屬性,有下面的三個註解:
- `@Document` 作用在類,標記實體類為文件物件,一般前兩個屬性
- indexName:對應索引庫名稱
- type:對應在索引庫中的型別
- shards:分片數量,預設5
- replicas:副本數量,預設1
- `@Id` 作用在成員變數,標記一個欄位作為id主鍵
- `@Field` 作用在成員變數,標記為文件的欄位,並指定欄位對映屬性:
- type:欄位型別,是是列舉:FieldType,可以是text、long、short、date、integer、object等
- text:儲存資料時候,會自動分詞,並生成索引
- keyword:儲存資料時候,不會分詞建立索引
- Numerical:數值型別,分兩類
- 基本資料型別:long、interger、short、byte、double、float、half_float
- 浮點數的高精度型別:scaled_float
- 需要指定一個精度因子,比如10或100。elasticsearch會把真實值乘以這個因子後儲存,取出時再還原。
- Date:日期型別
- elasticsearch可以對日期格式化為字串儲存,但是建議我們儲存為毫秒值,儲存為long,節省空間。
- index:是否索引,布林型別,預設是true
- store:是否儲存,布林型別,預設是false
- analyzer:分詞器名稱,這裡的`ik_max_word`即使用ik分詞器
示例 :
@Document(indexName = "item",type = "docs", shards = 1, replicas = 0)
public class Item {
@Id
private Long id;
@Field(type = FieldType.Text, analyzer = "ik_max_word")
private String title; //標題
@Field(type = FieldType.Keyword)
private String category;// 分類
@Field(type = FieldType.Double)
private Double price; // 價格
@Field(index = false, type = FieldType.Keyword)
private String images; // 圖片地址
}
ElasticsearchTemplate中提供了建立索引的API:
@Test
public void createIndex() {
// 建立索引,會根據Item類的@Document註解資訊來建立
esTemplate.createIndex(Item.class);
// 配置對映,會根據Item類中的id、Field等欄位來自動完成對映
esTemplate.putMapping(Item.class);
// 刪除索引
esTemplate.deleteIndex(Item.class);
// 根據索引名字刪除
//esTemplate.deleteIndex("item1");
}
操作資料:
public interface ItemRepository extends ElasticsearchRepository<Item,Long> {
}
@Autowired
private ItemRepository itemRepository;
@Test
public void index() {
//新增一個
Item item = new Item(1L, "小米手機7", " 手機","小米", 3499.00, "http://image.baidu.com/13123.jpg");
itemRepository.save(item);
//新增多個
List<Item> list = new ArrayList<>();
list.add(new Item(2L, "堅果手機R1", " 手機", "錘子", 3699.00, "http://image.baidu.com/13123.jpg"));
list.add(new Item(3L, "華為META10", " 手機", "華為", 4499.00, "http://image.baidu.com/13123.jpg"));
itemRepository.saveAll(list);
//elasticsearch中本沒有修改,它的是該是先刪除在新增,修改和新增是同一個介面,區分的依據就是id。
Item item = new Item(1L, "蘋果XSMax", " 手機", "小米", 3499.00, "http://image.baidu.com/13123.jpg");
itemRepository.save(item);
//查詢所有
Iterable<Item> list = this.itemRepository.findAll();
// 對某欄位排序查詢所有 Sort.by("price").descending() 降序 , Sort.by("price").ascending():升序
Iterable<Item> list = this.itemRepository.findAll(Sort.by("price").ascending());
for (Item item:list){
System.out.println(item);
}
}
自定義查詢1(在ItemRepository中):
Spring Data 的另一個強大功能,是根據方法名稱自動實現功能。
比如:你的方法名叫做:findByTitle,那麼它就知道你是根據title查詢,然後自動幫你完成,無需寫實現類。
當然,方法名稱要符合一定的約定:
Keyword | Sample |
---|---|
And |
`findByTitleAndPrice``findBy屬性名1And屬性名2 |
Or |
findByTitleOrPrice |
Is = |
findByTitle |
Not |
findByTitleNot |
Between |
findByPriceBetween |
LessThanEqual |
findByPriceLessThan |
GreaterThanEqual |
findByPriceGreaterThan |
Before |
findByPriceBefore |
After |
findByPriceAfter |
Like |
findByNameLike |
StartingWith |
findByNameStartingWith |
EndingWith |
findByNameEndingWith |
Contains/Containing |
findByNameContaining |
In |
findByNameIn(Collection<String>names) |
NotIn |
findByNameNotIn(Collection<String>names) |
Near |
findByStoreNear |
True |
findByAvailableTrue |
False |
findByAvailableFalse |
OrderBy |
findByAvailableTrueOrderByNameDesc |
例如:根據價格區間查詢
定義: List<Item> findByPriceBetween(double price1, double price2);
使用: List<Item> list = this.itemRepository.findByPriceBetween(2000.00, 3500.00);
自定義查詢2(在ItemRepository中):
matchQuery :詞條匹配 /(不分詞)
TermQuery :詞條匹配 /(分詞)
wildcardQuery :萬用字元匹配
fuzzyQuery :模糊匹配
booleanQuery :布林匹配
1.MUST和MUST:交集。
2.MUST和MUST_NOT:表示查詢結果中不能包含MUST_NOT所對應得查詢子句的檢索結果。
3.SHOULD與MUST_NOT:連用時,功能同MUST和MUST_NOT。
4.SHOULD與MUST連用時,結果為MUST子句的檢索結果,但是SHOULD可影響排序。
5.SHOULD與SHOULD:並集。
6.MUST_NOT和MUST_NOT:無意義,檢索無結果。
NativeSearchQueryBuilder :Spring提供的一個查詢條件構建器,幫助構建json格式的請求體