Web概述和HTML
ElasticSearch
1、概述
Elasticsearch 是一個分散式可擴充套件的實時搜尋和分析引擎,一個建立在全文搜尋引擎 Apache Lucene(TM) 基礎上的搜尋引擎.當然 Elasticsearch 並不僅僅是 Lucene 那麼簡單,它不僅包括了全文搜尋功能,還可以進行以下工作:
- 分散式實時檔案儲存,並將每一個欄位都編入索引,使其可以被搜尋。
- 實時分析的分散式搜尋引擎。
- 可以擴充套件到上百臺伺服器,處理PB級別的結構化或非結構化資料。
基本概念
先說Elasticsearch的檔案儲存,Elasticsearch是面向文件型資料庫,一條資料在這裡就是一個文件,用JSON作為文件序列化的格式,比如下面這條使用者資料:
{
"name" : "John",
"sex" : "Male",
"age" : 25,
"birthDate": "1990/05/01",
"about" : "I love to go rock climbing",
"interests": [ "sports", "music" ]
}
用Mysql這樣的資料庫儲存就會容易想到建立一張User表,有balabala的欄位等,在Elasticsearch裡這就是一個文件,當然這個文件會屬於一個User的型別,各種各樣的型別存在於一個索引當中。這裡有一份簡易的將Elasticsearch和關係型資料術語對照表:
關係資料庫 ⇒ 資料庫 ⇒ 表 ⇒ 行 ⇒ 列(Columns)
Elasticsearch ⇒ 索引(Index) ⇒ 型別(type) ⇒ 文件(Docments) ⇒ 欄位(Fields)
一個 Elasticsearch 叢集可以包含多個索引(資料庫),也就是說其中包含了很多型別(表)。這些型別中包含了很多的文件(行),然後每個文件中又包含了很多的欄位(列)。Elasticsearch的互動,可以使用Java API,也可以直接使用HTTP的Restful API方式,比如我們打算插入一條記錄,可以簡單傳送一個HTTP的請求:
PUT /megacorp/employee/1
{
"name" : "John",
"sex" : "Male",
"age" : 25,
"about" : "I love to go rock climbing",
"interests": [ "sports", "music" ]
}
更新,查詢也是類似這樣的操作,具體操作手冊可以參見Elasticsearch權威指南
ElasticSearch的搜尋是採用的倒排索引,具體的看倒排索引
2、ik分詞器
什麼是ik分詞器?
分詞:即把一段中文或者別的劃分為一個個關鍵字,我們在搜尋的時候會把自己的資訊進行分詞,會把資料庫中或者索引庫中的資料進行分詞,然後進行一個匹配操作,預設的中文分詞是將每個字看成一個詞,比如“我愛小胖”,就會被分成"我",”愛“,”小“,”胖“,這明顯是不符合要求的,所以我們需要安裝一箇中文分詞器來解決這個問題。
IK提供了兩個分詞演算法:ik_smart和ik_max_word,其中ik_smart為最少劃分,ik_max_word為最細度劃分。
測試:
ik_smart最少劃分
ik_max_word最細度劃分
我們還使用過程中,還可能遇到ik詞中沒有”張錦豪“這個詞,把它劃分成了"張","錦",”豪“。
這時候我們可以在ik分詞器中的配置檔案新增自己所需要的詞。
然後查詢出來的就是”張錦豪“
注意:型別為keyword型別的欄位不能被分詞器解析。
3、Restful風格
一種軟體架構風格,而不是標準,只是提供了一組設計原則和約束條件。它主要用於客戶端和服務端互動的軟體,基於這個風格設計的軟體可以更加簡潔,更有層次,更易於實現快取等機制。
基本的Rest命令說明:
method | url | 描述 |
---|---|---|
put | localhost:9200/索引名稱/型別名稱/文件id | 建立文件(指定id) |
post | localhost:9200/索引名稱/型別名稱 | 建立文件(隨機文件id) |
post | localhost:9200/索引名稱/型別名稱/文件id/_update | 修改文件 |
delete | localhost:9200/索引名稱/型別名稱/文件id | 刪除文件 |
get | localhost:9200/索引名稱/型別名稱/文件id | 查詢文件通過id |
post | localhost:9200/索引名稱/型別名稱/_search | 查詢所有資料 |
基礎測試
1、建立索引
資料新增成功,我們在建立的時候沒有標明資料欄位的型別,es會自動幫我們設定
我這也可以自己設定索引的資料型別,在建立的時候。
2、刪除索引
3、修改索引資料
- 通過put方式在原有的資料上直接修改,把原來的資料覆蓋掉(如果有些欄位沒寫,就會變為了空)
- 通過post的put方式指定文件id/_update修改資料(推薦使用這種方式,靈活性更高)
4、查詢索引資料
get 索引名
4、文件的花式查詢
1、簡單的查詢
這裡需要注意
複雜查詢
過濾查詢結果 相當於mysql種的select * 跟select 欄位的區別
排序
分頁查詢
bool 布林值查詢
多條件查詢 must就相當於sql中的and,所有條件都必須滿足
should 相當於or,只要滿足了其中一個條件的就可以
must_not 相當於not,非,不滿足
filter 過濾器
匹配多個條件查詢
term 精確查詢
term查詢是直接通過倒排索引指定的詞條程序精確的查詢的。
在使用term精確查詢時,型別為keyword的不會被分詞器解析。
多條件精確查詢
highlight 高亮
5、Spingboot整合
1、匯入依賴
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.6.1</version>
</dependency>
注意點:匯入的依賴版本一定要跟自己安裝的版本所對應
2、編寫配置檔案
@Configuration
public class EsConfig {
@Bean
public RestHighLevelClient restHighLevelClient(){
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(
new HttpHost("127.0.0.1", 9200,"http")
)
);
return client;
}
}
3測試
3.1、建立索引
@Autowired
@Qualifier("restHighLevelClient")
private RestHighLevelClient client;
//測試建立索引請求 相當於一個put請求
@Test
void contextLoads() throws IOException {
//建立索引請求
CreateIndexRequest request = new CreateIndexRequest("xiaopang_index");
//客戶端執行請求
CreateIndexResponse response = client.indices().create(request, RequestOptions.DEFAULT);
System.out.println(response);
}
3.2、查詢索引是否存在
//測試查詢索引
@Test
void contextLoads2() throws IOException {
//查詢索引請求
GetIndexRequest request = new GetIndexRequest("xiaopang_index");
//客戶端執行請求
boolean response = client.indices().exists(request,RequestOptions.DEFAULT);
System.out.println(response);
}
//結果返回true
3.3、刪除索引
//測試刪除索引
@Test
void contextLoads3() throws IOException {
//刪除索引請求
DeleteIndexRequest request = new DeleteIndexRequest("xiaopang_index");
//客戶端執行請求
AcknowledgedResponse delete = client.indices().delete(request, RequestOptions.DEFAULT);
System.out.println(delete.isAcknowledged());
}
//結果返回true
6、springboot整合之文件型操作
1、新增文件
//測試新增文件
@Test
public void addDocumentTest() throws IOException {
//建立物件
User user = new User("小胖", 13);
//建立請求
IndexRequest request = new IndexRequest("xiaopang");
//建立規則 相當於 put /xiaopang/_doc/1
//設定文件id
request.id("1");
//設定請求實踐
request.timeout("1s");
//將我們的user類封裝成json,放入請求中
request.source(JSON.toJSONString(user), XContentType.JSON);
//客戶端傳送請求,返回響應結果
IndexResponse index = client.index(request, RequestOptions.DEFAULT);
System.out.println(index.toString());
System.out.println(index.status());
}
//返回結果
IndexResponse[index=xiaopang,type=_doc,id=1,version=1,result=created,seqNo=0,primaryTerm=1,shards={"total":2,"successful":1,"failed":0}] //具體的資訊
CREATED //執行的狀態 新增
2、查詢文件資訊
//測試查詢文件資訊
@Test
public void selectDocumentTest() throws IOException {
//建立查詢請求
GetRequest request = new GetRequest("xiaopang", "1");
//判斷文件是否存在
boolean exists = client.exists(request, RequestOptions.DEFAULT);
System.out.println(exists);
GetResponse response = client.get(request, RequestOptions.DEFAULT);
System.out.println(response.getSource()); //獲取文件內容資訊
System.out.println(response); //獲取文件全部資訊
}
//返回結果
true
{name=小胖, age=13}
{"_index":"xiaopang","_type":"_doc","_id":"1","_version":1,"_seq_no":0,"_primary_term":1,"found":true,"_source":{"age":13,"name":"小胖"}}
3、修改文件資訊
//測試修改文件資訊
@Test
public void updateDocumentTest() throws IOException {
//建立修改請求
UpdateRequest request = new UpdateRequest("xiaopang", "1");
//設定響應時間
request.timeout("1s");
//建立新的user類,這裡相當於使用了put命令去修改文件資訊,直接覆蓋資訊
User user = new User("張錦豪", 18);
//將新的user放入請求
request.doc(JSON.toJSONString(user),XContentType.JSON);
//客戶端執行請求
UpdateResponse update = client.update(request, RequestOptions.DEFAULT);
System.out.println(update.status());
}
//返回結果
OK
4、刪除文件資訊
//測試刪除文件資訊
@Test
public void deleteDocumentTest() throws IOException {
DeleteRequest request = new DeleteRequest("xiaopang", "1");
request.timeout("1s");
DeleteResponse delete = client.delete(request, RequestOptions.DEFAULT);
System.out.println(delete.status());
}
//返回結果
ok
5、資料批量插入
//資料批量插入
@Test
public void test1() throws IOException {
BulkRequest bulkRequest = new BulkRequest();
bulkRequest.timeout("10s");
ArrayList<User> users = new ArrayList<>();
users.add(new User("xiaopang1",1));
users.add(new User("xiaopang2",1));
users.add(new User("xiaopang3",1));
users.add(new User("jinhao1",3));
users.add(new User("jinhao2",3));
users.add(new User("jinhao3",3));
for (int i = 0; i <users.size() ; i++) {
bulkRequest.add(
new IndexRequest("xiaopang")
.id(""+(i+1))
.source(JSON.toJSONString(users.get(i)),XContentType.JSON)
);
}
BulkResponse responses = client.bulk(bulkRequest, RequestOptions.DEFAULT);
System.out.println(responses.hasFailures());//是否失敗,false代表成功了
}
6、複雜查詢處理
@Test
public void test() throws IOException {
SearchRequest request = new SearchRequest("xiaopang");
//構建條件搜尋
SearchSourceBuilder builder = new SearchSourceBuilder();
TermQueryBuilder matchQuery = QueryBuilders.termQuery("name", "jinhao1");
builder.query(matchQuery);
request.source(builder);
builder.timeout(new TimeValue(60, TimeUnit.SECONDS));
SearchResponse search = client.search(request, RequestOptions.DEFAULT);
System.out.println(JSON.toJSONString(search));
System.out.println("============================================");
for (SearchHit hit : search.getHits().getHits()) {
System.out.println(hit.getSourceAsMap());
}
}