準(zhǔn)備環(huán)境
1劣纲、上一篇文章中搭建的本地測(cè)試環(huán)境
2、springboot最新版本 2.4.1(但是里面整合的客戶端是es 7.9.3 我們用的還是有點(diǎn)太新了筑悴,需要手動(dòng)修改一下ES的客戶端依賴)
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<!--重寫springboot給整理好的依賴用最新版本的ES客戶端-->
<elasticsearch.version>7.10.1</elasticsearch.version>
<java.version>1.8</java.version>
</properties>
我們使用的是es的highlevel rest api们拙。既然用就用點(diǎn)新貨這是我們的原則!8罅摺砚婆!
開整
在一開始我們先將ES與傳統(tǒng)mysql進(jìn)行一個(gè)比較方便在后面的使用中進(jìn)行橫向比較方便理解
在比較完對(duì)應(yīng)關(guān)系后看下es支持的字段數(shù)據(jù)類型,萬變不離文檔突勇,參考文檔地址 :https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-types.html
總結(jié)幾個(gè)常用的項(xiàng)目中可能用到的装盯。
下面總結(jié)一下我們項(xiàng)目中用到的數(shù)據(jù)結(jié)構(gòu)以及他們的相關(guān)屬性
- long 用于存儲(chǔ)id信息
- keyword 用于存儲(chǔ)手機(jī)號(hào)這種精準(zhǔn)信息
這里簡(jiǎn)單介紹一下keywords famliy,ES 支持keyword(主要用于存儲(chǔ)郵箱地址甲馋、id等信息比較合適)
constant_keyword(存儲(chǔ)大量相同的內(nèi)容比如用于存儲(chǔ)日志的話日志級(jí)別就用這個(gè)比較合適)埂奈,
wildcard 用于存儲(chǔ)需要進(jìn)行模糊搜索正則匹配的字段。 - text 需要對(duì)文本進(jìn)行全文檢索定躏,ES會(huì)對(duì)該字段進(jìn)行分詞账磺。
更多的的字段相關(guān)介紹 https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-types.html
項(xiàng)目中運(yùn)用
- 建立索引就叫測(cè)算記錄跟表名一樣即可 t_company_measure_record 建索引的json格式為
PUT t_company_measure_record
{
"settings": {
"number_of_replicas": 3,
"number_of_shards": 5
},
"mappings":{
"properties": {
"mobile": {
"type": "keyword"
},
"company_id": {
"type": "long"
},
"company_name": {
"type": "text",
"analyzer":"ik_max_word"
},
"company_city": {
"type": "text",
"analyzer":"ik_max_word"
},
"company_county": {
"type": "text",
"analyzer":"ik_max_word"
},
"legal_person_type": {
"type": "text",
"analyzer":"ik_max_word"
}
}
}
}
在配置公司名的時(shí)候我們使用的是ik分詞器
IK 分詞器的兩種模式 ik_max_word:最細(xì)力度切分。ik_smart:最粗力度切分痊远,最佳實(shí)踐往往是索引時(shí)用ik_max_word垮抗,在搜索時(shí)用ik_smart。
即:索引時(shí)最大化的將內(nèi)容分詞拗引,搜索時(shí)更精確的搜索到想要的結(jié)果借宵。
簡(jiǎn)單的crud
一、增
- 添加文檔json
POST t_company_measure_record/_doc/1
{
"mobile":"13888888888",
"company_id":1,
"company_name":"天云",
"company_city":"北京",
"company_county":"海淀"
}
這里做個(gè)簡(jiǎn)單說明就是url里面的_doc 這是es里面的type矾削,也就是有點(diǎn)像表的概念壤玫,但是這個(gè)會(huì)在ES8中徹底作廢
作廢原因如下
1豁护、在關(guān)系型數(shù)據(jù)庫中table是獨(dú)立的(獨(dú)立存儲(chǔ)),但es中同一個(gè)index中不同type是存儲(chǔ)在同一個(gè)索引中的(lucene的索引文件)欲间,因此不同type中相同名字的字段的定義(mapping)必須一致楚里。
2、不同類型的“記錄”存儲(chǔ)在同一個(gè)index中猎贴,會(huì)影響lucene的壓縮性能
- 添加文檔api
public boolean saveRecord(String indexName, int id, Map<String,Object> map) {
try {
IndexRequest request = new IndexRequest(indexName); //index名稱
request.id(String.valueOf(id));
request.source(map);
IndexResponse response = restHighLevelClient.index(request, RequestOptions.DEFAULT);
if (response.status().getStatus() == RestStatus.OK.getStatus()) {
return true;
}
} catch (Exception e) {
LOG.error("saveRecord error indexName = {},id = {}, map = {}",indexName,id, map, e);
}
return false;
}
二班缎、刪
- 刪除文檔json
DELETE t_company_measure_record/_doc/1
*刪除文檔api調(diào)用方式
public void delete() {
DeleteRequest deleteRequest = new DeleteRequest("t_company_measure_record");
deleteRequest.id("1");
try {
restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);
} catch (IOException e) {
e.printStackTrace();
}
}
三、改
更改分為兩種一種是全量更新她渴,一種是增量更新
全量更新只需要使用添加的方式就可以實(shí)現(xiàn)达址,下面將增量更新進(jìn)行記錄,也就是更新部分字段內(nèi)容或者添加部分字段
- 更改json
POST t_company_measure_record/_update/2
{
"doc":{
"mobile":"15552797319"
}
}
- 更改api
/**
* 更新某一個(gè)字段
*/
public void updatePart(){
UpdateRequest updateRequest = new UpdateRequest("t_company_measure_record","2");
IndexRequest indexRequest = new IndexRequest();
Map<String,String> mobileMap = new HashMap<>();
mobileMap.put("mobile","13552797310");
indexRequest.source(mobileMap);
updateRequest.doc(indexRequest);
try {
restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
} catch (IOException e) {
e.printStackTrace();
}
}
四趁耗、查詢
查詢相對(duì)來說復(fù)雜一些回想一下mysql where條件里面分為單個(gè)條件沉唠,多個(gè)條件,and苛败、or查詢
我們先看一個(gè)查一個(gè)字段的方法
- json請(qǐng)求
GET t_company_measure_record/_search
{
"query": {
"term": {
"mobile": "13552797310"
}
},
"from":0,
"size":10
}
term 與matchphrase的比較 term用于精確查找有點(diǎn)像 mysql里面的"=" match是先將查詢關(guān)鍵字分詞然后再進(jìn)行查找满葛,我們項(xiàng)目中為了讓搜索公司名稱更好所以使用了match的變種 matchphrase。term一般用在keywokrd類型的字段上進(jìn)行精確查找罢屈。
- api調(diào)用
/**
* 精確查找
*/
public void term() {
SearchRequest request = new SearchRequest("t_company_measure_record");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.termQuery("mobile","13552797310"));
searchSourceBuilder.from(0);
searchSourceBuilder.size(10);
request.source(searchSourceBuilder);
SearchResponse search = null;
try {
search = restHighLevelClient.search(request, RequestOptions.DEFAULT);
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(search);
}
- and 查詢也就是must查詢
json請(qǐng)求形式
GET t_company_measure_record/_search
{
"query": {
"bool":{
"must": [
{
"match_phrase": {
"company_name": "天云"
}
},
{
"term": {
"mobile": "13552797310"
}
}
]
}
},
"from":0,
"size":10
}
api 接口調(diào)用形式
public void must() {
SearchRequest request = new SearchRequest("t_company_measure_record");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
BoolQueryBuilder must = QueryBuilders.boolQuery().must(QueryBuilders.matchPhraseQuery("company_name", "天云")).must(QueryBuilders.matchPhraseQuery("mobile", "13552797310"));
searchSourceBuilder.query(must);
searchSourceBuilder.from(0);
searchSourceBuilder.size(10);
request.source(searchSourceBuilder);
SearchResponse search = null;
try {
search = restHighLevelClient.search(request, RequestOptions.DEFAULT);
System.out.println(search);
System.out.println(search.getHits().getTotalHits().value);
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(search);
}
OR查找
json 格式
GET t_company_measure_record/_search
{
"query": {
"bool":{
"should": [
{
"match_phrase": {
"company_name": "天云"
}
},
{
"term": {
"mobile": "13552797310"
}
}
]
}
},
"from":0,
"size":10
}
API 形式調(diào)用
/**
* OR 查詢
*/
public void should() {
SearchRequest request = new SearchRequest("t_company_measure_record");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
BoolQueryBuilder should = QueryBuilders.boolQuery().should(QueryBuilders.matchPhraseQuery("company_name", "天云")).should(QueryBuilders.matchPhraseQuery("mobile", "13552797310"));
searchSourceBuilder.query(should);
searchSourceBuilder.from(0);
searchSourceBuilder.size(10);
request.source(searchSourceBuilder);
SearchResponse search = null;
try {
search = restHighLevelClient.search(request, RequestOptions.DEFAULT);
System.out.println(search);
System.out.println(search.getHits().getTotalHits().value);
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(search);
}
基本使用方式暫時(shí)總結(jié)到這里嘀韧,抽空接續(xù)補(bǔ)充