一、顧名思義:
Elastic:靈活的;Search:搜尋引擎
二、官方簡介:
Elasticsearch是一個基於Lucene的搜尋伺服器。它提供了一個分散式多使用者能力的全文搜尋引擎,基於RESTful web介面。
三、優勢:
天然分片,天然叢集,天然索引--->正如他的名字一樣,查詢速度快,是他最大的優勢。
四、業務場景:
在大資料場景下,面對千萬級資料,我們一般都會在mysql上進行分庫分表。
比如我們根據公司名稱查詢公司詳細資訊,資料庫已經被分成若干個,表分成若干個,
我們是不知道具體在哪個庫,哪個表。分庫分表後,每個表都有一個唯一標識id,
這個id可以解析出庫表的字尾。那怎麼根據名稱獲取這個id呢,有一種思路就是公司名稱的md5,
然後解析到指定的索引庫表,然後我們就可以查詢到id,再根據id獲取其他資訊。
按照傳統模式,我們需要從mysql查詢兩次,第一次從索引庫查詢id,
然後根據id獲取其他資訊。面對億級資料,每過一次資料庫,效率都要打折扣。
於是es攜帶其天生的全文高速檢索優勢正式亮相:有以下3種方案:
1、將索引庫整合匯入es,我們優先從es中進行精確或者模糊匹配,然後再去mysql查詢具體資料。
2、將所有資料庫整合匯入es,直接從es查詢。
3、每次先從es查詢,es沒有從mysql查詢,然後更新到es。
大概分析下各自的優缺點。
1、可以大大提高檢索效率,但需要消耗巨大儲存與記憶體空間。
2、可以高效的支援精確與模糊查詢,空間與效率折中。中庸之道。
3、業務環節變多,風險多,查詢速度較低。
五、掀起蓋頭來(探索底層的奧祕)
很遺憾,這篇文章是掀不起來了,多次提筆,卻發現自己還是沒真正領悟,
無法用自己語言通俗的寫出來,後續專門寫一篇《掀起ElasticSearch的蓋頭》
六、重要知識點:
6.1、核心資料型別:
text:文字,預設會採用指定分詞器進行分詞,然後按照分詞進行倒排索引。
keyword:一個串就是一個整體,直接按照keyword進行倒排索引。
6.2、分詞:
分詞是模糊匹配的基礎,比如“中華人民共和國”,不同的分詞器拆分不同,假設會將其拆分成“中華”,“人民”,“共和國”。
於是當我們利用“中華“進行模糊查詢時,中華人民共和國就會被我們檢索到。
6.3、常用工具:
Kibana(ELK中的K):功能強大,酷炫。使用起來沒有eshead的”德福感“(絲滑)
es_head:小而精悍,你要的他都有。
七、事上煉:
SpringBoot+ElasticSearch
7.1、es資料來源:
7.1.1、利用logstash匯入
7.1.2、利用java api匯入
7.2、es操作:
ES 7.0版本中將棄用TransportClient
客戶端,已證明存在效能問題
目前大都採用:ElasticsearchTemplate
7.3、例子
7.3.1、es中的結構
"name": { "type": "text", #支援text,用於模糊匹配 "fields": { "keyword": { "ignore_above": 256, "type": "keyword" #支援keyword,使用者精確匹配 } } }
7.3.2、模糊匹配
1、將要查詢的詞,先進行分詞,再進行匹配(MatchQuery)
2、將要查詢的詞,作為一個整體,進行匹配(MatchPraseQuery),主要用這種
/** * 模糊匹配*/ public List getEidsFromEs(String name) { QueryBuilder queryBuilder = QueryBuilders.matchPhraseQuery(name, "name"); Pageable pageable = PageRequest.of(0, 10); //分頁 NativeSearchQuery searchQuery = new NativeSearchQueryBuilder() .withQuery(queryBuilder) .withIndices("index") .withTypes("_doc") .withPageable(pageable) .build(); AggregatedPage<doc> docs = template.queryForPage(searchQuery, doc.class); List<doc> eids = docs.getContent(); return eids; }
7.3.3精確匹配場景
1、單條件,單欄位(條件:”中華“,查詢es中name欄位)->termQuery
2、單條件,多欄位(條件:”中華“,查詢es中name,ename,com_name欄位)->termQuery+boolQuery
3、多條件,單欄位(條件:”中華“,”中國“,查詢es中name)->termsQuery
4、多條件,多欄位(條件:”中華“,”中國“,查詢es中name,ename,com_name欄位)->termQuery+boolQuery
/** * <單條件,單欄位>模糊匹配*/ public List getEidsFromEs(String name) { name = name + ".keyword"; //這很關鍵,增加字尾,啟用keyword精確匹配 QueryBuilder queryBuilder = QueryBuilders.termQuery(name, "name"); Pageable pageable = PageRequest.of(0, 10); //分頁 NativeSearchQuery searchQuery = new NativeSearchQueryBuilder() .withQuery(queryBuilder) .withIndices("index") .withTypes("_doc") .withPageable(pageable) .build(); AggregatedPage<doc> docs = template.queryForPage(searchQuery, doc.class); List<doc> eids = docs.getContent(); return eids; }
/** * <單條件,多欄位>模糊匹配*/ Map<String, Object> boolQueryMap = new HashMap<>(); Map<String, Object> boolQuery = new HashMap<>(); for (String key : keys) { boolQueryMap.put(key+".keyword", name); boolQuery.put(key+".keyword", Constants.SHOULD); } SearchQueryBean searchQueryBean = new SearchQueryBean() .setIndex(Constants.CBI_COMMON_INDEX).setType(Constants.CBI_COMMON_DOC) .setBoolQuery(boolQuery).setBoolQueryMap(boolQueryMap) .setPageNum(0).setPageSize(10) .setClazz(EsIndexDocument.class); BoolQueryBuilder booleanBoolQuery = QueryBuilders.boolQuery(); Iterator var3 = searchQueryBean.boolQueryMap.keySet().iterator(); while(var3.hasNext()) { Object key = var3.next(); if (searchQueryBean.getBoolQuery().containsKey(key)) { QueryBuilder queryBuilder = QueryBuilders.termQuery(key.toString(), searchQueryBean.boolQueryMap.get(key)); Method method = booleanBoolQuery.getClass().getMethod(searchQueryBean.getBoolQuery().get(key).toString(), QueryBuilder.class); method.invoke(booleanBoolQuery, queryBuilder); } } NativeSearchQuery searchQuery = this.buildNativeSearchQuery(searchQueryBean, booleanBoolQuery); return this.elasticsearchTemplate.queryForPage(searchQuery, searchQueryBean.getClazz());
寫到這裡,文章已經到了尾聲,此篇文章,主要講述了es的入門步驟,也僅僅是入門,學習還是在個人。
對文中有任何異議,可隨時留言或者郵箱反饋:wpt191@163.com,您的反饋是我們共同進步的催化劑。
還是那句話:學一門,愛一門,精一門,從知道到做到,還需要不停的努力與付出。