Elasticsearch 6.x版本全文檢索學習之倒排索引與分詞、Mapping 設置


 

Beats,Logstash負責數據收集與處理。相當於ETL(Extract Transform Load)。
Elasticsearch負責數據存儲、查詢、分析。
Kibana負責數據探索與可視化分析。

1、Elasticsearch的常見術語。注意:Elasticsearch6.x版本以后概念發生了變化。

2、索引Index:由具有相同字段的文檔列表組成。索引Index是文檔的集合。相當於數據庫中的數據表。

  Elasticsearch 6.x版本以后,一個索引Index下面最多只能建一個Type或者未來沒有Type了。索引中存儲具有相同結構的文檔(Document)。相當於數據表,數據表中有schema的概念,數據表有自己的表結構的定義。而Index的mapping相當於數據表的schema的概念,Index也需要定義字段名稱和類型的。

  每個索引都有自己的mapping定義,用於定義字段名和類型。一個集群可以有多個索引。

3、文檔Document:用戶存儲在es中的數據文檔。es中存儲的最小單元。相當於數據庫中的一行數據。每個文檔都有唯一的id標識,可以自行指定或者es自動生成。

Json Object,由字段Field組成,常見數據類型如下:
    字符串:text(分詞)、keyword(不分詞)。
    數值型:long、integer、short、byte、double、float、half_float、scaled_float。
    布爾型:boolean。
    日期:data。
    二進制:binary。
    范圍類型:interger_range、float_range、long_range、double_range、date_range。

4、Document MetaData。元數據,用於標注文檔的相關信息。

_index:文檔所在的索引名稱。
_type:文檔所在的類型名稱。
_id:文檔唯一的id。
_uid:組合id,由_type和_id組成(6.x_type不再起作用,同_id一樣)。
_source:文檔的原始Json數據,可以從這里獲取每個字段的內容。
_all:整合所有字段內容到該字段,默認禁用。

5、節點Node:一個Elasticsearch的運行實例,是集群的構成單元。

6、集群Cluster:由一個或者多個節點組成,對外提供服務。

7、Elasticsseach提供的Rest api。

Elasticsseach集群對外提供的RESTFul API,REST是REpresentational State Transfer的縮寫。
URI指定資源,如Index、Document等等。
Http Method,指明資源操作類型,如GET、POST、PUT、DELETE等等。
Rest API常用的兩種交互方式:Curl命令行、Kibana DecTools。
ElasticSearch有專門的Index API,用於創建(PUT)、查看(GET)、更新(Post)、刪除(Delete)索引配置等等。

 

8、Elasticsseach提供的Rest api使用。

  創建文檔,指定id創建文檔的api。創建文檔的時候,如果索引不存在,es會自動創建對應的index和type。

PUT /index/type/id{ "username":"zhangsan", "age":24 }

查詢文檔,指定要查詢的文檔id。_source存儲了文檔的完整原始數據。

get /index/type/id

查詢文檔,搜索所有文檔,用到_search,查詢語句json格式,放到http body中發送到es,如下所示:

get /index/type/_search 返回_id為1的文檔。 get /index/type/_search{ "query":{   "term":{   "_id":"1"   } } }

response結果,參數解釋如下所示:

 1 response結果,參數解釋如下所示:
 2 {
 3   "took" : 2,           # took是查詢耗時,單位是ms。         
 4   "timed_out" : false,
 5   "_shards" : {
 6     "total" : 5,
 7     "successful" : 5,
 8     "skipped" : 0,
 9     "failed" : 0
10   },
11   "hits" : { # hits是命中的結果集。
12     "total" : 1, # total是符合條件的總文檔數。
13     "max_score" : 0.2876821,
14     "hits" : [  # hits是返回的文檔詳情數據數組,默認前10個文檔。
15       {
16         "_index" : "test_index", # _index是索引名稱。
17         "_type" : "doc",
18         "_id" : "1", # _id是文檔的id。
19         "_score" : 0.2876821, # _score是文檔的得分。
20         "_source" : { # _source是文檔的詳情。
21           "username" : "wangwu",
22           "age" : 24
23         }
24       }
25     ]
26   }
27 }

批量創建文檔API,es允許一次創建多個文檔,從而減少網絡傳輸開銷,提升寫入速率。endponit為_bulk,即url最后是_bulk,http method是post請求,如下所示:

action_type包含,index(如果存在則覆蓋)、update、create(如果存在則報錯)、delete這幾種類型。

es允許一次查詢多個文檔,endpoint為_mget,如下所示:

9、Elasticsearch的倒排索引與分詞。舉例,書的目錄頁與索引頁,目錄頁對應正排索引,索引頁對應倒排索引。es存儲的是一個json格式的文檔,其中包含多個字段,每個字段會有自己的倒排索引。

  a、正排索引就是文檔Id到文檔內容,單詞的關聯關系。倒排索引,就是單詞到文檔Id的關聯關系。

  b、倒排索引是搜索引擎的核心,主要包含兩個部分。單詞詞典(Term Dictionary),倒排列表(Posting List),Posting是倒排索引項。

  c、單詞詞典(Term Dictionary)是倒排索引的重要組成。

一是記錄所有文檔的單詞,一般都比較大,
二是記錄單詞到倒排列表的關聯信息,記錄了單詞關聯了那些文檔,記錄一下關聯信息,就可以找到關聯的文檔的id,通過關聯id找到真正的文檔信息。

  d、倒排索引中的倒排列表。

倒排列表(Posting List)記錄了單詞對應的文檔集合,由倒排索引項(Psoting)組成。
倒排索引項(Posting)主要包含如下信息:
    文檔Id,用於獲取原始信息。
    單詞頻率(TF,Term Frequency),記錄該單詞在該文檔中的出現次數,用於后續相關性算分。
    位置(Position),記錄單詞在文檔中的分詞位置(多個),用於做此語搜索(Phrase Query)。
    偏移(Offset),記錄單詞在文檔的開始和結束位置,用於做高亮顯示。

10、分詞,是指將文本轉換成一系列單詞(term or token)的過程,也可以叫做文本分詞,在es里面稱為Analysis,如下所示:

  分詞器,負責進行分詞,分詞器是es中專門處理分詞的組件,英文名稱為Analyzer。分詞器的調用順序,Character Filters ->Tokenizer ->Token Filter,它的組成如下所示:

  Character Filters,針對原始文本進行處理,比如去除html特殊標記符。
  Tokenizer,將原始文本按照一定規則切分為單詞。
  Token Filter,針對Tokenizer處理的單詞就行再加工,比如轉小寫,刪除或者新增等等處理。

11、Analyzer api,es提供了一個測試分詞的api接口,方便驗證分詞效果,endpoint是_analyze。

  a、可以直接指定analyzer進行測試。

  b、可以直接指定索引中的字段進行測試。

  c、可以自定義分詞器進行測試。

12、Elasticsearch自帶分詞器,包含Standard、Simple、Whitespace、Stop、Keyword、Pattern、Language,如下所示:

a、Standard Analyzer,默認分詞器,特性為:a、按照切分,支持多語言,b、小寫處理。
    包含Tokenizer(Standard)和Token Filters(Standard -> Lower case -> Stop[disabled by default])。
b、Simple Analyzer,特性為:a、按照非字母進行切分,b、小寫處理。
    包含Tokenizer(Lower Case)。
c、Whitespace Analyzer,特性為:a、按照空格進行切分。
    包含Tokenizer(Whitespace)。
d、Stop Analyzer,Stop word指語氣助詞等修飾性的此語,比如the、an、的、這等等。特性為,a、相比Simple Analyzer多了Stop word處理。
    包含Tokenizer(Lower Case),Token Filters(Stop)。
e、Keyword Analyzer,特性為,a、不分詞,直接將輸入作為一個單詞輸出。
    包含Tokenizer(Keyword)。
f、    Pattern Analyzer,特性為,a、通過正則表達式自定義分隔符。b、默認是\W+,即非字詞的符號作為分隔符。
    包含Tokenizer(Pattern),Token Filters(Lower case -> Stop[disabled by default])。
g、Language Analyzer,提供了30+常見語言的分詞器。
    arabic、armenian、basque、bengali、brazilian、bulgarian、catalan、cjk、czech、danish、dutch、english。

13、中文分詞,指的是將一個漢字序列切分成一個一個單獨的詞。在英文中,單詞之間是以空格作為自然分界符,漢語中詞沒有一個形式上的分界符。

常用中文分詞系統。
  IK中文分詞器。
      a、實現中英文單詞的切分,支持ik_smart,ik_maxword等模式。
      b、可以自定義詞庫,支持熱更新分詞詞典。
  jieba中文分詞器。
    a、python中最流行的分詞系統,支持分詞和詞性標注。
    b、支持繁體分詞,自定義分詞,並行分詞等等。

14、自定義分詞,當自帶的分詞無法滿足需求時候,可以自定義分詞。通過自定義Character Filters、Tokenizer和Token Filter實現。

1)、Character Filters。
    a、在Tokenizer之前對原始文本進行處理,比如增加、刪除或者替換字符等等。
    b、自帶的如下所示:
        Html Strip去除html標簽和轉換html實體。
        Mapping進行字符替換操作。
        Pattern Replace進行正則匹配替換。
    c、會影響后續Tokenizer解析的postion和offset的信息。
2)、Tokenizer。
    a、將原始文本按照一定規則切分為單詞(term or token)。
    b、自帶的如下所示:
        standard按照單詞進行分割。
        letter按照非字符類進行分割。
        whitespace按照空格進行分割。
        UAX URL Email按照standard分割,但不會分割郵箱和url。
        NGram和Edge NGram連詞分割。
        Path Hierarchy按照文件路徑進行切割。
3)、Token Filter。
    a、對於Tokenizer輸出的單詞(term)進行增加、刪除、修改等等操作。
    b、自帶的如下所示:    
        lowercase將所有term轉換為小寫。
        stop刪除stop words。
        NGram和Edge NGram連詞分割。
        Synonym添加近義詞的term。

15、分詞使用說明,索引時分詞和查詢時候分詞的選擇。

分詞使用說明,索引時分詞和查詢時候分詞的選擇。
1)、分詞會在如下兩個時機使用:
    a、創建或者更新文檔的時候(Index Time),會對相應的文檔進行分詞處理。
    b、查詢的時候(Search Time),會對查詢語句進行分詞。
2)、索引時分詞,是通過配置Index Mapping中每個字段的analyzer屬性實現的,不指定分詞的時候,默認使用standard分詞器。    
3)、查詢時分詞的指定方式有如下幾種。
    a、查詢的時候通過analyzer指定分詞器。
    b、通過index mapping設置search_analyzer實現,這個時候可以設置查詢時分詞,同事設置查詢時分詞。
4)、一般情況下,不需要特定指定查詢時分詞器,直接使用索引時分詞器即可,否則會出現無法匹配的情況。
5)、分詞的使用建議。
    a、明確字段是否需要分詞,不需要分詞的字段就將type設置為keyword,可以節省空間和提高寫性能。
    b、善用_analyze_api,查看文檔具體分詞結果。
    c、多動手測試,查看文檔具體的分詞結果。

16、Elasticsearch Mapping設置。類似數據庫中的表結構定義,主要作用如下所示:

a、定義Index下的字段名(Field Name)。
b、定義字段的類型,比如數據型,字符串型,布爾型等等。
c、定義倒排索引相關的配置,比如是否索引,記錄position等等。

如何獲取到一個索引Index的mapping呢,如下所示:

如何自定義mapping呢,自定義mapping的api,如下所示:

自定義Mapping注意事項。

1)、Mapping中的字段類型一旦設定以后,禁止直接修改,原因如是所示,Lucene實現的倒排索引生成后不允許進行修改。
    如果要進行修改字段類型的話,重新建立新的索引,然后做reindex操作。
2)、允許新增字段,通過dynamic參數來控制字段的新增。因為新增字段,類型不定,對於es來說,只是新增了一個倒排索引。dynamic參數是和properties一個級別的參數配置。
    a、true(默認),允許自動新增字段。
    b、false,不允許自動新增字段,但是文檔可以正常寫入,但無法對字段進行查詢等操作。
    c、strict文檔不能寫入,報錯。
3)、copy_to參數,將該字段的值復制到目標字段,實現類似_all的作用,不會出現在_source中,只用來搜索使用。copy_to參數和type一個級別的參數。
4)、index參數,控制當前字段是否索引,默認為true,即記錄索引,false不記錄,即不可以搜索。index參數和type一個級別的參數。如果不希望被查詢即可設置為false。
5)、index_options用於控制倒排索引記錄的內容,有如下4種配置。index_options參數和type一個級別的參數。
  a、docs只記錄doc id。
  b、freqs記錄doc id和term frequencies。
  c、positions記錄doc id、term frequencies和term position。
  d、offsets記錄doc id、term frequencies、term position和character offsets。
  e、text類型默認配置為positions,其他默認配置為docs。記錄內容越多,占用空間越大。
6)、null_value,當字段遇到null值得時候得處理策略,默認為null,即空值,此時es會忽略該值,可以通過設定該值設定字段的默認值。null_value參數和type一個級別的參數。
更多參數詳見官網文檔即可。

17、Elasticsearch的數據類型。

1)、核心的數據類型(字段field對應的類型type)。
    a、字符串類型text(分詞的)、keyword(不分詞的)。
    b、數值型:long、integer、short、byte、double、float、half_float、scaled_float。
    c、布爾型:boolean。
    d、日期:data。
    e、二進制:binary。
    f、范圍類型:interger_range、float_range、long_range、double_range、date_range。
2)、復雜數據類型。
    a、數組類型array。
    b、對象類型object。
    c、嵌套類型nested object。
3)、地理位置數據類型。
    a、geo_point。
    b、geo_shape。
4)、專用類型。
    a、記錄ip地址ip。
    b、實現自動補全completion。
    c、記錄分詞數token_count。
    d、記錄字符串hash值murmur3。
    e、percolator。
    f、join。
5)、多字段特性multi_fields。
    允許對同一個字段采用不同得配置,比如分詞,常見例子如對人名實現拼音搜索。只需要在人名種新增一個子字段為pinyin即可。

18、Dynamic Mapping,es可以自動識別文檔字段類型,從而降低用戶使用成本,如下所示。

es是依靠json文檔的字段類型來實現自動識別字段類型,支持的類型如下所示:

19、dynamic日期與數字識別。

1)、日期的自動識別可以自行配置日期格式,以滿足各種需求。
    a、默認是["strict_date_optional_time","yyyy/MM/dd HH:mm:ss Z || yyyy/MM/dd Z"]
    b、strict_date_optional_time是ISO datetime的格式,完整格式類似下面所示:
        YYYY-MM-DDThh:mm:ssTZD。例如,1994-07-12T19:20:30+01:00
    c、dynamic_date_formats可以自定義日期類型。該參數是在type參數下一級的參數。
    d、date_detection可以關閉日期自動識別的機制。該參數是在type參數下一級的參數。
2)、字符串是數字的時候,默認不會自動識別為整數,因為字符串中出現數字是完全合理的。
    a、numeric_detection可以開啟字符串中數字的自動識別。該參數是在type參數下一級的參數。

20、dynamic-template(動態模板)簡介。

1)、允許根據es自動識別的數據類型、字段名等來動態設定字段類型,可以實現如下效果。
    a、所有字符串類型都設定為keyword類型,即默認不分詞的。
    b、所有以message開頭的字段都設定為text類型,即分詞。
    c、所有以long_開頭的字段都設定為long類型。
    d、所有自動匹配為double類型都設定為float類型,以節省空間。
2)、匹配規則一般有如下幾個參數。
    a、match_mapping_type匹配es自動識別的字段類型,如boolean、long、string等等。
    b、match,unmatch匹配字段名。
    c、path_match,path_unmatch匹配路徑。
3)、字符串默認使用keyword類型。es默認會為字符串設置為text類型,並增加一個keyword的子字段。

字符串默認使用keyword類型。es默認會為字符串設置為text類型,並增加一個keyword的子字段。

動態模板映射以后是這樣的。

以message開頭的字段都設置為text類型。 dynamic_templates,數組,可以指定多個匹配規則。可以設定多個模板,執行順序,從上到下的。

21、自定義mapping的建議。

自定義mapping的操作步驟如下所示。
    a、寫一條文檔到es的臨時索引中,獲取es自動生成的mapping。
    b、修改步驟a得到的mapping,自定義相關配置。
    c、使用步驟b的mapping創建實際所需索引。

最方便的是根據動態模板進行創建。

22、索引模板。

  a、索引模板,英文為Index Template,主要用於在新建索引的時候自動應用預先設定的配置。簡化索引創建的操作步驟。
    可以設定索引的配置和mapping。
    可以有多個模板,根據order設置,order大的覆蓋小的配置。

 

作者:別先生

博客園:https://www.cnblogs.com/biehongli/

如果您想及時得到個人撰寫文章以及著作的消息推送,可以掃描上方二維碼,關注個人公眾號哦。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM