《ElasticSearch入門》一篇管夠,持續更新

PeterWilliam發表於2020-06-15

一、顧名思義:

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,您的反饋是我們共同進步的催化劑。

還是那句話:學一門,愛一門,精一門,從知道到做到,還需要不停的努力與付出。

 

相關文章