天天看點

第三章 Elasticsearch基礎搜尋(一)一、管理Elasticsearch索引和文檔二、資料檢索和分析

一、管理Elasticsearch索引和文檔

在es中,索引和文檔是REST接口操作的最基本資源,是以對索引和文檔的管理也是我們必須要知道的。索引一般是以索引名稱出現在REST請求操作的資源路徑上,而文檔是以文檔ID為辨別出現在資源路徑上。映射類型_doc也可以認為是一種資源,但在es7中廢除了映射類型,是以可以_doc也視為一種接口。

1、索引的管理

在前面的學習中我們已經知道,GET用來擷取資源,PUT用來更新資源,DELETE用來删除資源。是以對索引,GET用來檢視索引,PUT用來建立索引,DELETE用來删除索引,還有一個HEAD請求,用來檢驗索引是否存在。除此之外,對索引的管理還有:

1.1、列出所有索引

GET /_cat/indices?v

第三章 Elasticsearch基礎搜尋(一)一、管理Elasticsearch索引和文檔二、資料檢索和分析

也可以通過ElasticSearch提供的接口直接查詢:http://192.168.0.101:9200/_cat/indices

第三章 Elasticsearch基礎搜尋(一)一、管理Elasticsearch索引和文檔二、資料檢索和分析

1.2、關閉索引和打開

關閉索引指令:

POST /open-soft/_close

除了删除索引,還可以選擇關閉它們。如果關閉了一個索引,就無法通過Elasticsearch來讀取和寫人其中的資料,直到再次打開它。在現實世界中,最好永久地儲存應用日志,以防要檢視很久之前的資訊。另一方面,在Elasticsearch中存放大量資料需要增加資源。對于這種使用案例,關閉舊的索引非常有意義。你可能并不需要那些資料,但是也不想删除它們。一旦索引被關閉,它在Elasticsearch記憶體中唯一的痕迹是其中繼資料,如名字以及分片的位置。如果有足夠的磁盤空間,而且也不确定是否需要在那個資料中再次搜尋,關閉索引要比删除索引更好。關閉它們會讓你非常安心,永遠可以重新打開被關閉的索引,然後在其中再次搜尋。

重新打開

POST /open-soft/_open

2、配置索引

通過settings參數配置索引,索引的所有配置項都以index開頭。索引的管理分為靜态設定和動态設定兩種。

2.1、靜态設定

隻能在索引建立時或在狀态為closed index(閉合索引)上設定,主要配置索引主分片、壓縮編碼、路由等相關資訊index.number_of_shards主分片數,預設為5;隻能在建立索引時設定,不能修改index.shard.check_on_startup是否應在索引打開前檢查分片是否損壞,當檢查到分片損壞将禁止分片被打開。false:預設值;checksum:檢查實體損壞;true:檢查實體和邏輯損壞,這将消耗大量記憶體和CPU;fix:檢查實體和邏輯損壞。

有損壞的分片将被叢集自動删除,這可能導緻資料丢失index.routing_partition_size自定義路由值可以轉發的目的分片數。預設為1,隻能在索引建立時設定。此值必須小于index.number_of_shards。

index.codec預設使用LZ4壓縮方式存儲資料,也可以設定為best_compression,它使用DEFLATE方式以犧牲字段存儲性能為代價來獲得更高的壓縮比例。如:

PUT /test1/_settings

{

"index.number_of_shards":3,

"index.codec":"best_compression"

}

2.2、動态設定

通過接口“_settings”進行,同時查詢配置也通過這個接口進行,比如:

get _settings

get /open-soft/_settings

get /open-soft,test1/_settings

配置索引則通過:

PUT test1/_settings

{

  "refresh_interval": "2s"

}

2.3、常用的配置參數如下:

index.number_of_replicas:每個主分片的副本數,預設為1。

index.auto_expand_replicas:基于可用節點的數量自動配置設定副本數量,預設為false(即禁用此功能)。

index.refresh_interval:執行重新整理操作的頻率,預設為1s。可以設定為-1以禁用重新整理。

index.max_result_window:用于索引搜尋的from+size的最大值,預設為10000。

index.blocks.read_only:設定為true使索引和索引中繼資料為隻讀,false為允許寫入和中繼資料更改。

index.blocks.read:設定為true可禁用對索引的讀取操作。

index.blocks.write:設定為true可禁用對索引的寫入操作。

index.blocks.metadata:設定為true可禁用索引中繼資料的讀取和寫入。

index.max_refresh_listeners:索引的每個分片上可用的最大重新整理偵聽器數。

index.max_docvalue_fields_search:一次查詢最多包含開啟doc_values字段的個數,預設為100。

index.max_script_fields:查詢中允許的最大script_fields數量,預設為32。

index.max_terms_count:可以在terms查詢中使用的術語的最大數量,預設為65536。

index.routing.allocation.enable:控制索引分片配置設定,All所有分片、primaries主分片、new_primaries新建立分片、none不分片。

index.routing.rebalance.enable:索引的分片重新平衡機制。all、primaries、replicas、none。

index.gc_deletes:文檔删除後(删除後版本号)還可以存活的周期,預設為60s。

index.max_regex_length:用于正在表達式查詢(regex query)正在表達式長度,預設為1000。

2.4、配置映射

通過_mapping接口進行,在我們前面的章節中,已經展示過了。

GET /open-soft/_mapping

或者隻看某個字段的屬性:

GET /open-soft/_mapping/field/lang

{

  "open-soft" : {

    "mappings" : {

      "lang" : {

        "full_name" : "lang",

        "mapping" : {

          "lang" : {

            "type" : "text"

          }

        }

      }

    }

  }

}

修改映射,當然就是通過put或者post方法了。但是要注意,已經存在的映射隻能添加字段或者字段的多類型。但是字段建立後就不能删除,大多數參數也不能修改,可以改的是ignore_above。是以設計索引時要做好規劃,至少初始時的必要字段要規劃好。

3、文檔的管理

3.1、增加文檔

增加文檔,我們在前面的章節已經知道了,比如:

PUT /open-soft/_doc/1

{

  "name": "Apache Hadoop",

  "lang": "Java",

  "corp": "Apache",

  "stars": 200

}

如果增加文檔時,在Elasticsearch中如果有相同ID的文檔存在,則更新此文檔,比如執行:

PUT /open-soft/_doc/1

{

  "name": "Apache Hadoop2",

  "lang": "Java8",

  "corp": "Apache",

  "stars": 300

}

則會發現已有文檔的内容被更新了。 

3.2、文檔的id

當建立文檔的時候,如果不指定ID,系統會自動建立ID。自動生成的ID是一個不會重複的随機數。使用GUID算法,可以保證在分布式環境下,不同節點同一時間建立的_id一定是不沖突的。比如:

POST /open-soft/_doc

{

  "message": "Hello"

}

3.3、查詢文檔

GET /open-soft/_doc/1

3.4、更新文檔

前面我們用put方法更新了已經存在的文檔,但是可以看見他是整體更新文檔,如果我們要更新文檔中的某個字段怎麼辦?需要使用_update 接口。

POST /open-soft/_update/1/

{

  "doc": {

    "year": 2016

  }

}

第三章 Elasticsearch基礎搜尋(一)一、管理Elasticsearch索引和文檔二、資料檢索和分析

文檔中存在year字段,更新year字段的值,如果不存在year字段,則會新增year字段,并将值設為2016。

update接口在文檔不存在時提示錯誤,如果希望在文檔不存在時建立文檔,則可以在請求中添加upsert 參數或doc_as_upsert參數,例如:

POST /open-soft/_update/5

{

  "doc": {

    "year": "2020"

  },

  "upsert": {

    "name": "hankin Framework",

    "corp": "hankin "

  }

}

或者:

POST /open-soft/_update/6

{

  "doc": {

    "year": "2020"

  },

  "doc_as_upsert": true

}

upsert參數定義了建立新文檔使用的文檔内容,而doc_as_upsert參數的含義是直接使用doc參數中的内容作為建立文檔時使用的文檔内容。

3.5、删除文檔

DELETE /open-soft/_doc/1

二、資料檢索和分析

為了友善我們學習,我們導入kibana為我們提供的範例資料。目前為止,我們已經探索了如何将資料放入Elasticsearch, 現在來讨論下如何将資料從Elasticsearch中拿出來,那就是通過搜尋。畢竟,如果不能搜尋資料,那麼将其放入搜尋引擎的意義又何在呢?幸運的是,Elasticsearch提供了豐富的接口來搜尋資料,涵蓋了Lucene所有的搜尋功能。因為Elasticsearch允許建構搜尋請求的格式很靈活,請求的建構有無限的可能性。要了解哪些查詢和過濾器的組合适用于你的資料,最佳的方式就是進行實驗,是以不要害怕在項目的資料上嘗試這些組合,這樣才能弄清哪些更适合你的需求。

1、添加測試資料(這裡使用飛行資料樣例)

第三章 Elasticsearch基礎搜尋(一)一、管理Elasticsearch索引和文檔二、資料檢索和分析

2、_search接口

所有的REST搜尋請求使用_search接口,既可以是GET請求,也可以是POST請求,也可以通過在搜尋URL中指定索引來限制範圍。

_search接口有兩種請求方法,一種是基于URI的請求方式,另一種是基于請求體的方式,無論哪種,他們執行的文法都是基于DSL(ES為我們定義的查詢語言,基于JSON的查詢語言),隻是形式上不同。我們會基于請求體的方式來學習。比如說:

GET kibana_sample_data_flights/_search

{

  "query": {

    "match_all": {}

  }

}

GET kibana_sample_data_flights/_search

{

  "query": {

    "match_none": {}

  }

}

當然上面的查詢沒什麼太多的用處,因為他們分别代表比對所有和全不比對。是以我們經常要使用各種文法來進行查詢,一旦選擇了要搜尋的索引,就需要配置搜尋請求中最為重要的子產品。這些子產品涉及文檔傳回的數量,選擇最佳的文檔傳回,以及配置不希望哪些文檔出現在結果中等等。

■ query-這是搜尋請求中最重要的組成部分,它配置了基于評分傳回的最佳文檔,也包括了你不希望傳回哪些文檔。

■ size-代表了傳回文檔的數量。

■ from-和size一起使用,from用于分頁操作。需要注意的是,為了确定第2頁的10項結果,Elasticsearch 必須要計算前20個結果。如果結果集合不斷增加,擷取某些靠後的翻頁将會成為代價高昂的操作。

■ _source指定_ source字段如何傳回,預設是傳回完整的_ source 字段。通過配置_ source将過濾傳回的字段。如果索引的文檔很大,而且無須結果中的全部内容,就使用這個功能。請注意,如果想使用它,就不能在索引映射中關閉_ source字段。

■ sort預設的排序是基于文檔的得分。如果并不關心得分,或者期望許多文檔的得分相同,添加額外的 sort 将幫助你控制哪些文檔被傳回。 

1.1、結果起始和頁面大小

命名适宜的from和size字段,用于指定結果的開始點,以及每“頁"結果的 數量。舉個例子,如果發送的from值是7,size值是5,那麼Elasticsearch将傳回第8、9、10、11和12項結果(由于from參數是從0開始,指定7就是從第8項結果開始)。如果沒有發送這兩個參數,Elasticsearch 預設從第一項結果開始 (第0項結果),在回複中傳回10項結果。

例如:

GET kibana_sample_data_flights/_search

{

  "from": 100,

  "size": 20,

  "query": {

    "term": {

      "DestCountry": "CN"

    }

  }

}

但是注意,from與size的和不能超過index. max_result_window這個索引配置項設定的值。預設情況下這個配置項的值為10000,是以如果要查詢10000條以後的文檔,就必須要增加這個配置值。例如,要檢索第10000條開始的200條資料,這個參數的值必須要大于10200,否則将會抛出類似“Result window is too

large'的異常。

由此可見,Elasticsearch在使用from和size處理分頁問題時會将所有資料全部取出來,然後再截取使用者指定範圍的資料傳回。是以在查詢非常靠後的資料時,即使使用了from和size定義的分頁機制依然有記憶體溢出的可能,而max_result_ window設定的10000條則是對Elastiesearch的一.種保護機制。

那麼Elasticsearch為什麼要這麼設計呢?首先,在網際網路時代的資料檢索應該通過相似度算法,提高檢索結果與使用者期望的附和度,而不應該讓使用者在檢索結果中自己挑選滿意的資料。以網際網路搜尋為例,使用者在浏覽搜尋結果時很少會看到第3頁以後的内容。假如使用者在翻到第10000條資料時還沒有找到需要的結果,那麼他對這個搜尋引擎一定會非常失望。

1.2、_source 參數

元字段_source中存儲了文檔的原始資料。如果請求中沒有指定_source,Elasticsearch預設傳回整個_ source,或者如果_ source 沒有存儲,那麼就隻傳回比對文檔的中繼資料:_ id、_type、_index 和_score。

例如:

GET kibana_sample_data_flights/_search

{

  "query": {

    "match_all": {}

  },

  "_source": [

    "OriginCountry",

    "DestCountry"

  ]

}

你不僅可以傳回字段清單,還可以指定通配符。例如,如果想同時傳回" DestCountry "和" DestWeather "字段,可以這樣配置_ source: "Dest*"。也可以使用通配字元串的數組來指定多個通配符,例如_ source:[" Origin*", "* Weather "]。

GET kibana_sample_data_flights/_search

{

  "query": {

    "match_all": {}

  },

  "_source": [

    "Origin*",

    "*Weather"

  ]

}

不僅可以指定哪些字段需要傳回,還可以指定哪些字段無須傳回。比如:

GET kibana_sample_data_flights/_search

{

  "_source": {

    "includes": [

      "*.lon",

      "*.lat"

    ],

    "excludes": "DestLocation.*"

  }

}

1.3、排序

大多搜尋最後涉及的元素都是結果的排序( sort )。如果沒有指定sort排序選項,Elasticsearch傳回比對的文檔的時候,按照_ score 取值的降序來排列,這樣最為相關的(得分最高的)文檔就會排名在前。為了對字段進行升序或降序排列,指定映射的數組,而不是字段的數組。通過在sort中指定字段清單或者是字段映射,可以在任意數量的字段上進行排序。

例如:

GET kibana_sample_data_flights/_search

{

  "from": 100,

  "size": 20,

  "query": {

    "match_all": {}

  },

  "_source": [

    "Origin*",

    "*Weather"

  ],

  "sort": [

    {

      "DistanceKilometers": "asc"

    },

    {

      "FlightNum": "desc"

    }

  ]

}

3、檢索

目前為止所進行的幾乎所有搜尋請求雖然有些條件限制,但是限制條件主要是在規定ES傳回的查詢結果中哪些字段傳回,哪些字段不傳回,對于哪些文檔傳回,哪些文檔不傳回,其實沒有多少限制。真正如何更精确的找到我們需要的文檔呢?這就需要我們需要使用帶條件的搜尋,主要包括兩類,基于詞項的搜尋和基于全文的搜尋。

2.1、基于詞項的搜尋 

2.1.1、term查詢:

對詞項做精确比對,數值、日期等等,如:

GET kibana_sample_data_flights/_search

{

  "query": {

    "term": {

      "dayOfWeek": 3

    }

  }

}

對于字元串而言,字元串的精确比對是指字元的大小寫,字元的數量和位置都是相同的,詞條(term)查詢使用字元的完全比對方式進行文本搜尋,詞條查詢不會分析(analyze)查詢字元串,給定的字段必須完全比對詞條查詢中指定的字元串。比如:

GET kibana_sample_data_flights/_search

{

  "query": {

    "term": {

      "OriginCityName": "Frankfurt am Main"

    }

  }

}

但是如果我們執行:

GET kibana_sample_data_flights/_search

{

  "query": {

    "term": {

      "OriginCityName": "Frankfurt"

    }

  }

}

結果卻是是以可以把term查詢了解為SQL語句中where條件的等于号。

terms查詢可以把terms查詢了解為SQL語句中where條件的in操作符:

GET kibana_sample_data_flights/_search

{

  "query": {

    "terms": {

      "OriginCityName": [

        "Frankfurt am Main",

        "Cape Town"

      ]

    }

  }

}

Elasticsearch在terms查詢中還支援跨索引查詢,這類似于關系型資料庫中的一對多或多對多關系。比如,使用者與文章之間就是一對多關系,可以在使用者索引中存儲文章編号的數組以建立這種對應關系,而将文章的實際内容儲存在文章索引中(當然也可以在文章中儲存使用者ID)。如果想将ID為1的使用者發表的所有文章都找出來,在文章索引中查詢時為:

POST /open-soft/_search

{

  "query": {

    "terms": {

      "_id": {

        "index": "open-soft",

        "id": "1",

        "path": "articles"

      }

    }

  }

}

在上面的例子中,terms要比對的字段是id,但比對值則來自于另一個索引。

這裡用到了index、id和path三個參數,它們分别代表要引用的索引、文檔ID和字段路徑。在上面的例子中,先會到open-soft索引中在找id為1的文檔,然後取出articles字段的值與articles索引裡的_id做對比,這樣就将使用者1的所有文章都取出來了。

2.2.1、range查詢和exists查詢

range查詢和過濾器的含義是不言而喻的,它們查詢介于一定範圍之内的值,适用于數字、日期甚至是字元串。為了使用範圍查詢,需要指定某個字段的上界和下界值。例如:

GET kibana_sample_data_flights/_search

{

  "query": {

    "range": {

      "FlightDelayMin": {

        "gte": 100,

        "lte": 200

      }

    }

  }

}

可以查詢出延誤時間在100~200之間的航班。其中:

gte:大于等于(greater than and equal)

gt:大于(greater than)

lte:小于等于(less than and equal)

lt:大于(less than )

boost:相關性評分(後面的章節會講到相關性評分)

exists:查詢檢索字段值不為空的的文檔,無論其值是多少,在查詢中通過field字段設定檢查非空的字段名稱,隻能有一個。

2.1.3、prefix查詢

prefix查詢允許你根據給定的字首來搜尋詞條,這裡字首在同樣搜尋之前是沒有經過分析的。例如:

GET kibana_sample_data_flights/_search

{

  "query": {

    "prefix": {

      "DestCountry": "C"

    }

  }

}

找到航班目的國家中所有以C開頭的文檔。

2.1.4、wildcard查詢和regexp查詢

wildcard查詢就是通配符查詢。使用字元串可以讓Elasticsearch使用*通配符替代任何數量的字元(也可以不含)或者是使用?通配符替代單個字元。

例如,有5個單詞:bacon,barn,ban和baboon、 bam,

“ba*n”的查詢會比對bacon、barn、ban和baboon這是因為‘*’号可以比對任何字元序列,而查詢“ba?n”隻會比對“barn",因為‘?’任何時候都需要比對一個單獨字元。也可以混合使用多個‘*’和‘?’字元來比對更為複雜的通配模闆,比如 f*f?x 就可以比對 firefox。

GET kibana_sample_data_flights/_search

{

  "query": {

    "wildcard": {

      "Dest": "*Marco*"

    }

  }

}

使用這種查詢時,需要注意的是wildcard查詢不像match等其他查詢那樣輕量級。查詢詞條中越早出現通配符( *或者? ),Elasticsearch就需要做更多的工作來進行比對。例如,對于查詢詞條“h*”,Elasticsearch 必須比對所有以“h”開頭的詞條。如果詞條是“hi*”,Elasticsearch 隻需搜尋所有“hi" 開頭的詞條,這是“h”開頭的詞條集合的子集,規模更小。考慮到額外開支和性能問題,在實際生産環境中使用wildcard 查詢之前,需要先考慮清楚,并且盡量不要讓通配符出現在查詢條件的第一位。

當然Elasticsearch也支援正則regexp查詢,比如:

GET kibana_sample_data_flights/_search

{

"query":{"regexp":{

"字段名":"正規表達式"

}

}

}

2.2、文本分析

詞條(term)查詢和全文(fulltext)查詢最大的不同之處是:全文查詢首先分析(Analyze)查詢字元串,使用預設的分析器分解成一系列的分詞,term1、term2、termN,然後從索引中搜尋是否有文檔包含這些分詞中的一個或多個。

是以,在基于全文的檢索裡,ElasticSearch引擎會先分析(analyze)查詢字元串,将其拆分成小寫的分詞,隻要已分析的字段中包含詞條的任意一個,或全部包含,就比對查詢條件,傳回該文檔;如果不包含任意一個分詞,表示沒有任何文檔比對查詢條件。

這裡就牽涉到了ES裡很重要的概念,文本分析,當然對應非text類型字段來說,本身不存在文本資料詞項提取的問題,是以沒有文本分析的問題。 

2.2.1、分析什麼?

分析( analysis )是在文檔被發送并加入反向索引之前,Elasticsearch在其主體上進行的操作。在文檔被加入索引之前,Elasticsearch讓每個被分析字段經過一系列的處理步驟。

■字元過濾:使用字元過濾器轉變字元。

■文本切分為分詞:将文本切分為單個或多個分詞。

■分詞過濾:使用分詞過濾器轉變每個分詞。

■分詞索引:将這些分詞存儲到索引中。

比如有段話“I like ELK,it include Elasticsearch&LogStash&Kibana”,分析以後的分詞為: i like elk it include elasticsearch logstash kibana。

2.2.2、字元過濾

Elasticsearch首先運作字元過濾器(char filter)。這些過濾器将特定的字元序列轉變為其他的字元序列。這個可以用于将HTML從文本中剝離,或者是将任意數量的字元轉化為其他字元(也許是将“I love u 2”這種縮寫的短消息糾正為I love you too。在“I like ELK……”的例子裡使用特定的過濾器将“&” 替換為“and”。

2.2.3、切分為分詞

在應用了字元過濾器之後,文本需要被分割為可以操作的片段。底層的Lucene是不會對大塊的字元串資料進行操作。相反,它處理的是被稱為分詞(token)的資料。分詞是從文本片段生成的,可能會産生任意數量(甚至是0)的分詞。例如,在英文中一個通用的分詞是标準分詞器,它根據空格、換行和破折号等其他字元,将文本分割為分詞。在我們的例子裡,這種行為表現為将字元串“I like ELK,it include Elasticsearch&LogStash&Kibana”分解為分詞 I like ELK it include Elasticsearch and LogStash Kibana。 

2.2.4、分詞過濾器

一旦文本塊被轉換為分詞,Elasticsearch将會對每個分詞運用分詞過濾器(token filter)。這些分詞過濾器可以将一個分詞作為輸入,然後根據需要進行修改,添加或者是删除。最為有用的和常用的分詞過濾器是小寫分詞過濾器,它将輸入的分詞變為小寫,確定在搜尋詞條"nosql"的時候,可以發現關于"NoSq"的聚會。分詞可以經過多于1個的分詞過濾器,每個過濾器對分詞進行不同的操作,将資料塑造為最佳的形式,便于之後的索引。在上面的例子,有3種分詞過濾器:第1個将分詞轉為小寫,第2個删除停用詞(停止詞)"and",第三個将詞條"tools" 作為"technologies" 的同義詞進行添加。

2.3、分詞索引

當分詞經曆了零個或者多個分詞過濾器,它們将被發送到Lucene進行文檔的索引。這些分詞組成了第1章所讨論的反向索引。

2.4、分析器

所有這些不同的部分,組成了一個分析器( analyzer ),它可以定義為零個或多個字元過濾器,1個分詞器、零個或多個分詞過濾器。Elasticsearch中提供了很多預定義的分析器。我們可以直接使用它們而無須建構自己的分析器。

4、配置分析器

4.1、_analyze接口

GET /_analyze

POST /_analyze

GET /<index>/_analyze

POST /<index>/_analyze

可以使用_analyze API來測試analyzer如何解析我們的字元串的,在我們下面的學習中,我們會經常用到這個接口來測試。

4.2、分詞綜述

因為文本分詞會發生在兩個地方:

建立索引:當索引文檔字元類型為text時,在建立索引時将會對該字段進行分詞;

搜尋:當對一個text類型的字段進行全文檢索時,會對使用者輸入的文本進行分詞。

是以這兩個地方都可以對分詞進行配置。

4.3、建立索引時

ES将按照下面順序來确定使用哪個分詞器:

1)先判斷字段是否有設定分詞器,如果有,則使用字段屬性上的分詞器設定;

2)如果設定了analysis.analyzer.default,則使用該設定的分詞器;

3)如果上面兩個都未設定,則使用預設的standard分詞器。

4.3.1、設定索引預設分詞器:

PUT test

{

  "settings": {

    "analysis": {

      "analyzer": {

        "default": {

          "type": "simple"

        }

      }

    }

  }

}

還可以為索引配置内置分詞器,并修改内置的部分選項修改它的行為:

PUT test2

{

  "settings": {

    "analysis": {

      "analyzer": {

        "my_analyzer": {

          "type": "standard",

          "stopwords": [

            "the", "a","an", "this", "is"

          ]

        }

      }

    }

  }

}

4.3.2、如何為字段指定内置分詞器

PUT test3

{

  "mappings": {

    "properties": {

      "title": {

        "type": "text",

        "analyzer": "standard",

        "search_analyzer": "simple"

      }

    }

  }

}

4.3.3、甚至還可以自定義分詞器

我們綜合來看看分詞的設定,并且通過_analyzer接口來測試分詞的效果:

PUT /my_index

{

  "settings": {

    "analysis": {

      "analyzer": {

        "std_english": {

          "type": "standard",

          "stopwords": "_english_"

        }

      }

    }

  },

  "mappings": {

    "properties": {

      "my_text": {

        "type": "text",

        "analyzer": "standard",

        "fields": {

          "english": {

            "type": "text",

            "analyzer": "std_english"

          }

        }

      }

    }

  }

}

我們首先,在索引my_index中配置了一個分析器std_english,std_english中使用了内置分析器 standard,并将standard的停止詞模式改為英語模式_english_(預設是沒有的),對字段my_text配置為多資料類型,分别使用了兩種分析器,standard和std_english。

POST /my_index/_analyze

{

  "field": "my_text",

  "text": "The old brown cow"

}

POST /my_index/_analyze

{

  "field": "my_text.english",

  "text": "The old brown cow"

}

第三章 Elasticsearch基礎搜尋(一)一、管理Elasticsearch索引和文檔二、資料檢索和分析

通過上述運作我們可以看到,分析器std_english中的The被删除,而standard中的并沒有。這是因為 my_text.english配置了單獨的停止詞。

4.4、文檔搜尋時

文檔搜尋時使用的分析器有一點複雜,它依次從如下參數中如果查找文檔分析器,如果都沒有設定則使用standard分析器:

1)搜尋時指定analyzer參數。

2)建立索引時指定字段的search_analyzer屬性。

3)建立索引時字段指定的analyzer屬性。

4)建立索引時setting裡指定的analysis.analyzer.default_search。

5)如果都沒有設定則使用standard分析器。

比如:搜尋時指定analyzer查詢參數

GET my_index/_search

{

  "query": {

    "match": {

      "message": {

        "query": "Quick foxes",

        "analyzer": "stop"

      }

    }

  }

}

指定字段的analyzer和seach_analyzer:

DELETE /my_index

PUT my_index2

{

  "mappings": {

    "properties": {

      "title": {

        "type": "text",

        "analyzer": "whitespace",

        "search_analyzer":"simple"

      }

    }

  }

}

指定索引的預設搜尋分詞器:

DELETE /my_index

PUT my_index

{

  "settings": {

    "analysis": {

      "analyzer": {

        "default": {

          "type": "simple"

        },

        "default_seach": {

          "type": "whitespace"

        }

      }

    }

  }

}

繼續閱讀