Elasticsearch range 查詢 ES 5.x TODO

在數據結構方面,新增了多個 range 字段類型,有什麼用呢,如今你能夠計算連續數據的交併集,能夠是時間範圍,也能夠是數值範圍。html

好比數據存放的是會議信息,航班有一個 range 字段,裏面存的是會議的開始和結束時間,你經過對應的 range 查詢能夠很方便的查詢,獲得某個時間點哪些會議同時正在進行,那段時間會議室有空閒,能夠預訂等等。node

首先看看怎麼定義吧,下面的這個例子, mapping 裏面設置字段的 type 爲 date_range 即表示一個時間的範圍字段:es6

POST http://node1:9200/my_index
{
	"mappings":{
		"my_data":{
			"properties":{
				"name":{
					"type":"text"
				},
				"expected_attendees":{
					"type":"integer_range"
				},
				"time":{
					"type":"date_range",
					"format":"yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
				}
			}
		}
	}
}

POST http://node1:9200/my_index/my_data/1
{
	"name":"elasticon",
	"expected_attendees" : {
		"gte":5000,
		"lte":10000
	},
	"time":{
		"gte":"2017-03-03 20:20:20",
		"lte":"2017-04-04 04:04:04"
	}
}

POST http://node1:9200/my_index/_search
{
	"query":{
		"range":{
			"expected_attendees":{
				"gte":5000,
				"lte":10000,
				"relation":"within"
			}
		}
	}
}

POST http://node1:9200/my_index/_search
{
	"query":{
		"range":{
			"time":{
				"gte":"2017-03-03",
				"lte":"2017-04-05",
				"relation":"within"
			}
		}
	}
}

 

下一個特性值得介紹的就是 _all 字段的移除數據庫

關於 _all 這個字段,場景其實就是爲了知足快速檢索的需求,當你不知道 mapping 裏面有什麼字段的狀況下,你也可以自由的進行搜索, 因此爲了實現這個需求,就有一個 _all 字段,它會把其餘字段的內容都拷貝到這個字段裏面,而後都當成 string 類型來處理,因此就存在了數據的冗餘了,另外數字當成 string 也不能很好的壓縮,而且都在 _all 一個字段,因此只能用一種分析器,在高亮的時候也是對這個 _all 字段進行的高亮,而不是真實的字段值,顯示起來效果也很差。json

如今 query_string 和 simple_query_string 查詢引入了一個 all_fields 模式,在沒有指定字段的狀況下,默承認以自動選擇相關類型的字段分別執行查詢,自動幫你展開,使用起來更加簡單,另外, _all 字段將在 6.0 默認禁用且不可配置。數據結構

接下來,咱們看看搜索的高亮,咱們知道文本高亮是搜索體驗的重要的一環,經過顯示匹配結果的文本塊並對關鍵字進行高亮可以讓咱們對搜索結果有一個直觀的認識。app

如今有一個新的高亮器: Unified Highlighter,你們可能會問,目前 ES 默認已經提供了 3 種不一樣的高亮器,爲何還會有一個新的輪子呢,由於以前的用法有點複雜 , 用戶選擇起來比較困難,新的 unified highlighter 目的就是簡化高亮的使用,能夠支持前面 3 種高亮類型的自動選擇。curl

 

還有一個是 keyword 類型能夠經過 normalizer 來進行標準化了, keyword 類型相比 text 類型就是不能分詞,可是可能一樣須要進行相應的標準化處理,好比統一轉成小寫,移除標點符號等等,使用方式和 analyzer 同樣,好比下面的需求:機器學習

儘管設置了 keyword 類型,可是我一樣是須要對文本進行處理的啊,用戶不可能輸入的徹底都是同樣,錯一個大小寫,可能就查不出來了。elasticsearch

新的 normalizer 使用起來 很簡單,和 analyzer 基本同樣,專門用於 keyword 類型,以下:

POST http://node1:9200/my_index
{
	"settings":{
		"analysis":{
			"normalizer":{
				"my_normalizer":{
					"type":"custom",
					"char_filter":[],
					"filter":[
						"lowercase",
						"asciifolding"
					]
				}
			}
		}
	},
	"mappings":{
		"my_data":{
			"properties":{
				"foo":{
					"type":"keyword",
					"normalizer":"my_normalizer"
				}
			}
		}
	}
}

POST http://node1:9200/my_index/my_data/1
{
	"foo":"Zhangsan"
}

POST http://node1:9200/my_index/_search
{
	"query":{
		"match":{
			"foo":"ZHANGSAN"
		}
	}
}
-->
{
    "took": 25,
    "timed_out": false,
    "_shards": {
        "total": 5,
        "successful": 5,
        "failed": 0
    },
    "hits": {
        "total": 1,
        "max_score": 0.2876821,
        "hits": [
            {
                "_index": "my_index",
                "_type": "my_data",
                "_id": "1",
                "_score": 0.2876821,
                "_source": {
                    "foo": "Zhangsan"
                }
            }
        ]
    }
}

另外一個就是 Multi-Word Synonyms,以前是不支持同義詞中間有空格分割的,分詞的時候會幫你切分開,搜索的時候不能正確處理詞組這種同義詞,以下面的場景。

這裏有一組同義詞,看起來沒毛病。

有一個 phrase 查詢,看起來也沒毛病。

個人同義詞過濾器就不對了,以下:

new is old ?這是什麼狀況?

由於分詞的時候,把他們單個字拆開進行的同義處理。新的多詞同義詞採用 graph 方式處理,很好的解決了上面的問題。

同義詞如今能夠支持詞組了,也就是說同義詞若是是由多個詞組成的,不會在分詞的時候被傻傻的拆開,而是正確的處理。

還一個就是字段摺疊( Field collapsing),這個特性比較有意思,你能夠在搜索的時候,按某個字段做爲維度進行去重,我這裏寫過一篇詳細的博客,有興趣的能夠去看看:

http://elasticsearch.cn/article/132

Cancellable searches

ES 的搜索,對於一些耗時較長的查詢,之前是沒有辦法取消的,除了幹掉節點重來或者等待結束,沒有辦法,如今能夠經過 ES 的任務管理機制來進行取消了, 5.3 已經提供。感興趣的能夠查看文檔:

https://www.elastic.co/guide/en/Elasticsearch/reference/5.3/search.html#global-search-cancellation

Partitioned term aggs

ES 的聚合功能很強大吧, term aggs 相信也是你們經常使用的一種,若是遇到字段裏面惟一 term 不少的場景,聚合起來不僅是慢,可能還無法正常運行。

如今 term aggs 提供了一種分區的概念,你能夠對一個字段,分 n 次進行聚合,分而治之,有興趣的能夠看看文檔:

https://www.elastic.co/guide/en/Elasticsearch/reference/5.3/search-aggregations-bucket-terms-aggregation.html#_filtering_values_with_partitions

另外,當你的集羣變紅的時候,你是否是手忙腳亂過,檢查一大堆配置,訪問一大堆接口來查看究竟是哪裏出了問題。

如今方便了,新增的 /_cluster/allocation/explain 接口可以直接告訴你哪裏出了問題:

Java REST Client 也有了更新, ES 以前提供了一個偏底層的 Java HTTP REST client,可是用起來太費勁,須要手動拼 JSON,如今, Java REST Client 分紅了 Java High Level REST Client 和 Java Low Level REST Client, High Level 基於 Low Level 來實現,顧名思義,提供更多用戶方便的接口調用, High Level REST Client 將提供和 Transport Client 相似的接口,不用手動去拼接 QueryDSL 的 JSON 了,目測在 5.5 版本提供。

據說大家有不少集羣在跑?那你有沒有用過 tribe node 來訪問多個集羣呢?, tribe-node 的工做方式是合併多個集羣的元數據到一塊兒,負責請求的轉發。

不過 tribe-node 有幾個問題,首先,他須要和各個集羣的每一個節點創建鏈接,另外 tribe-node 的 配置的靜態的,修改以後須要重啓 tribe-node,每一個集羣的元數據變化以後都須要進行合併,頻繁的操做十分影響性能,而且集羣的索引名稱必須保證不能相同,同時,經過 tribe-node 只能只讀,沒法建立索引,再者,跨集羣查詢,會將全部的分片的數據都放到 tribe-node 上進行 reduce,若是分片不少,可能出現 OOM 等問題。

新引入的 cross-cluster 跨集羣功能就是爲了方便以一種更優雅的方式來替換掉 tribe-node。

先來上一張圖,裏面能夠看到如何建立一個 cross-cluster。

能夠看到,集羣的任何節點都能執行跨集羣操做,節點的元數據不須要頻繁更新,集羣間索引基於命名空間進行了隔離。

 

什麼是命名空間?

GET sales:*,r_and_d:logs*/_search

{

"query": { … }

}

能夠看到上面的 QueryDSL,正常的索引前面有 namespace:這樣的前綴,這就是命名空間,也就是選擇不一樣的集羣。

不只能夠動態設置多個集羣的訪問,也不須要重啓節點。集羣間互相不受影響,更沒有頻繁的元數據的同步。

Kibana 可以徹底訪問多個集羣,且能建立索引和進行修改,具有完整訪問權限。

跨集羣訪問只須要很輕量級的幾個鏈接,不須要和每一個節點都創建鏈接,這個功能在 5.3 已經支持。

Batched Search Reduce Phases

另外,之前的搜索的 reduce 操做都是要等到把每一個分片的結果都拿到本地以後再作合併,因此爲了不海量分片形成的資源大量佔用的問題,以前是有一個最多 1000 個分片的軟限制,也就是一個搜索最多隻能檢索 1000 個分片,如今新增的 batched search reduce phases 提供了分批進行 reduce 的行爲,也就是不用所有拿到以後再作 reduce,而是拿到足夠的分片(默認 512)以後就開始 作 reduce,而後拿到合併結果,釋放相關的資源,繼續獲取其餘的分片數據繼續進行 reduce,這樣就能處理海量的數據了,這個功能在 5.4 發佈。

ES 6.0 展望

上面的這些功能基本會在 5.x 提供,而 es6.0 早已在路上了,有不少特性值得期待:

稀疏性 Doc Values 的支持,你們知道 es 的 doc values 是列式存儲,文檔的原始值都是存放在 doc values 裏面的,而稀疏性是指,一個索引裏面,文檔的結構實際上是多樣性的,可是鬱悶的是隻要一個文檔有這個字段,其餘全部的文檔儘管沒有這個字段,可也都要承擔這個字段的開銷,因此會存在磁盤空間的浪費,而這塊的改進就是這個問題。

Index sorting,即在索引階段的排序,即咱們查詢的時候有時候會根據某個字段的值進行排序,好比時間、編號等等,若是在索引的時候提取排好序,那麼搜索或聚合的時候就會很是快,相應的直接走預先排序好的索引就好了。固然索引的時候會要增長額外開銷,適合不怎麼變化的索引的場景。

順序號的支持,每一個 es 的操做都有一個順序編號,這個屬於 es 內部的一個功能,能夠提供:快速的分片副本恢復或同步;跨數據中心的節點恢復;甚至提供一個 Changes API 等等;

無縫滾動升級,使之可以從 5 的最後一個版本滾動升級到 6 的最後一個版本,不須要集羣的完整重啓。無縫滾動升級,也就是不用停服務,在線升級,補充一下。

 

什麼是最後一個版本?

也就是 6 發佈第一個版本,好比 6.0 的時候, 5 的對應的那個最後的發佈的版本,好比 5.5,那麼 5.5 能夠直接滾動升級到 6.0。而且這兩個版本咱們稱爲主要版本,他們還支持跨大版本的搜索。就是前面提到的 cross-cluster 特性,不一樣的版本也能支持跨集羣訪問,以下:

下面還有一些:

Removal of types,在 6.0 裏面,開始不支持一個 index 裏面存在多個 type 了,全部的新的 index 都將只有一個虛擬的固定的 type: doc 來代替,基於 type 的 parent-child 關係將經過單獨的 join 字段來實現, type 會在 7.0 完全移除。

Index-template inheritance,索引版本的繼承,目前索引模板是全部匹配的都會合並,這樣會形成索引模板有一些衝突問題, 6.0 將會只匹配一個,索引建立時也會進行驗證。

Load aware shard routing, 基於負載的請求路由,目前的搜索請求是全節點輪詢,那麼性能最慢的節點每每會形成總體的延遲增長,新的實現方式將基於隊列的耗費時間自動調節隊列長度,負載高的節點的隊列長度將減小,讓其餘節點分攤更多的壓力,搜索和索引都將基於這種機制。

已經關閉的索引將也支持 replica 的自動處理,確保數據可靠。

X-Pack 的部分特性:

6.0 的部分特性預告就上面這些,我猜下面的特性你也一樣感興趣:

Elasticsearch-SQL

Elasticsearch 官方也要支持的 SQL 特性了。

默認提供了一個 CLI 工具,能夠很方便的執行 SQL 查詢,主要面向管理人員,提升常見操做的使用效率。

Kibana 裏面也能夠直接執行。

另外也兼容 JDBC 協議,現存的不少基於 JDBC 協議的各類 SQL 工具及 BI 工具都能直接把 es 當數據庫來鏈接和進行數據分析。

使用 ES 變得更加輕量級,使用起來無依賴。

機器學習

去年 Elastic 收購了業界領先的行爲數據分析廠商 Prelert,如今相關產品已經集成進入了 X-Pack 的機器學習模塊,能夠快速的實現基於 ES 數據的行爲分析,藉助 ES 的海量實時處理能力,採用非監督機器學習來識別異常行爲。

上圖是機器學習自動識別出來的異常數據點。

本文只是 ES 最近的衆多改進的一部分,有關更詳細的更新內容還以具體的版本發佈記錄爲準。

ElasticStack 的其餘開源項目也有不少有意思的改進和 feature,願意瞭解更多的,能夠關注咱們官方及社區的活動:

http://elasticsearch.cn/article/141

Q&A 

提問:可否說說 ES 是如何在 lucene 上實現分佈式的?

這個不是一句話可以說清楚點,能夠參考咱們的權威指南:

http://elasticsearch.cn/book/elasticsearch_definitive_guide_2.x/distributed-docs.html

提問:能否組織一些 ES 常見的複雜模型構建思路探討這樣的論題。主要是探討如何實現與優化。我想這是在座的同窗都會有遇到的問題。

曾勇:複雜模型須要具體分析,能夠參看咱們的權威指南:

http://elasticsearch.cn/book/elasticsearch_definitive_guide_2.x/modeling-your-data.html

提問:ES 與 solr 對比有什麼優點?技術選型時如何考慮?

曾勇:網上的對比有不少,我就不一一贅述了,若是沒有用過 solr,那建議直接使用 ES 吧,上手更快更簡單。另外網上的優劣比較其實也要結合本身的實際場景,實踐出真知。

問:請問下,若是我有 9G 的數據導入,如何導最快?以前 curl @xxx.txt 方式,可是數據文件一大 curl 標準格式導入就不行了。

曾勇:走 bulk 方式確定是最快的,txt 內容是什麼格式呢,利用一些現存的工具,能夠試試,好比 logstash,記得選擇 bulk 模式。導入的時候,有不少參數也對速度有幫助,這個就要去看看索引的優化這塊的內容了。

相關文章
相關標籤/搜索