一、管理Elasticsearch索引和文檔
在es中,索引和文檔是REST接口操作的最基本資源,是以對索引和文檔的管理也是我們必須要知道的。索引一般是以索引名稱出現在REST請求操作的資源路徑上,而文檔是以文檔ID為辨別出現在資源路徑上。映射類型_doc也可以認為是一種資源,但在es7中廢除了映射類型,是以可以_doc也視為一種接口。
1、索引的管理
在前面的學習中我們已經知道,GET用來擷取資源,PUT用來更新資源,DELETE用來删除資源。是以對索引,GET用來檢視索引,PUT用來建立索引,DELETE用來删除索引,還有一個HEAD請求,用來檢驗索引是否存在。除此之外,對索引的管理還有:
1.1、列出所有索引
GET /_cat/indices?v

也可以通過ElasticSearch提供的接口直接查詢:http://192.168.0.101:9200/_cat/indices
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
}
}
文檔中存在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、添加測試資料(這裡使用飛行資料樣例)
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"
}
通過上述運作我們可以看到,分析器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"
}
}
}
}
}