全文檢索是指計算機索引程序經過掃描文章中的每個詞,對每個詞創建一個索引,指明該詞在文章中出現的次數和位置,當用戶查詢時,檢索程序就根據事先創建的索引進行查找,並將查找的結果反饋給用戶的檢索方式。這個過程相似於經過字典中的檢索字表查字的過程。html
根據http://lucene.apache.org/java/docs/index.html定義:java
Lucene是一個高效的,基於Java的全文檢索庫。算法
因此在瞭解Lucene以前要費一番工夫瞭解一下全文檢索。數據庫
那麼什麼叫作全文檢索呢?這要從咱們生活中的數聽說起。apache
咱們生活中的數據整體分爲兩種:結構化數據和非結構化數據。json
固然有的地方還會提到第三種,半結構化數據,如XML,HTML等,當根據須要可按結構化數據來處理,也可抽取出純文本按非結構化數據來處理。緩存
非結構化數據又一種叫法叫全文數據。安全
參考連接:https://blog.csdn.net/genghaihua/article/details/88946228app
es的底層存儲使用lucene,主要包含行存儲(storefiled),列存儲(docvalues)和倒排索引(invertindex)。dom
大多數使用場景中,沒有必要同時存儲這三個部分,能夠經過下面的參數來作適當調整
1 mapping type index 設置
"_source": {
"enabled": false
}
StoreFiled: 行存,其中佔比最大的是_source字段,它控制doc原始數據的存儲。在寫入數據時,ES把doc原始數據的整個json結構體當作一個string,存儲爲_source字段。查詢時,能夠經過_source字段拿到當初寫入時的整個json結構體。 因此,若是沒有取出整個原始json結構體的需求,能夠經過下面的命令,在mapping中關閉_source字段或者只在_source中存儲部分字段,數據查詢時仍可經過ES的docvalue_fields獲取全部字段的值。
注意:關閉_source後, update, update_by_query, reindex等接口將沒法正常使用,因此有update等需求的index不能關閉_source。
2 字段doc_values設置
"doc_values": false
控制列存。ES主要使用列存來支持sorting, aggregations和scripts功能。
3 字段索引設置
"index": false
控制倒排索引。ES默認對於全部字段都開啓了倒排索引,用於查詢。
DSL (domain-specific language),領域特定語言指的是專一於某個應用程序領域的計算機語言,又譯做領域專用語言。不一樣於普通的跨領域通用計算機語言(GPL),領域特定語言只用在某些特定的領域。
6、倒排索引
正排索引:
倒排索引:
Shard(分片)
一個Shard就是一個Lucene實例,是一個完整的搜索引擎。一個索引能夠只包含一個Shard,只是通常狀況下會用多個分片,能夠拆分索引到不一樣的節點上,分擔索引壓力。
segment
elasticsearch中的每一個分片包含多個segment,每個segment都是一個倒排索引;在查詢的時,會把全部的segment查詢結果彙總歸併後做爲最終的分片查詢結果返回;
在建立索引的時候,elasticsearch會把文檔信息寫到內存bugffer中(爲了安全,也一塊兒寫到translog),定時(可配置)把數據寫到segment緩存小文件中,而後刷新查詢,使剛寫入的segment可查。
雖然寫入的segment可查詢,可是尚未持久化到磁盤上。所以,仍是會存在丟失的可能性的。
因此,elasticsearch會執行flush操做,把segment持久化到磁盤上並清除translog的數據(由於這個時候,數據已經寫到磁盤上,不在須要了)。
當索引數據不斷增加時,對應的segment也會不斷的增多,查詢性能可能就會降低。所以,Elasticsearch會觸發segment合併的線程,把不少小的segment合併成更大的segment,而後刪除小的segment。
segment是不可變的,當咱們更新一個文檔時,會把老的數據打上已刪除的標記,而後寫一條新的文檔。在執行flush操做的時候,纔會把已刪除的記錄物理刪除掉。
當你對一個文檔創建索引時,它僅存儲在一個primary shard上。ES是怎麼知道一個文檔應該屬於哪一個shard?當你建立一個新的文檔時,ES是怎麼知道應該把它存儲至shard1仍是shard2? 這個過程不能隨機無規律的,由於之後咱們還要將它取出來。它的路由算法是:
shard = hash(routing) % number of primary_shards
routing的值能夠是文檔的id,也能夠是用戶本身設置的一個值。hash將會根據routing算出一個數值而後%primary shards的數量。這也是爲何primary_shards在index建立時就不能修改的緣由。
咱們能夠向這個集羣的任何一臺NODE發送請求,每個NODE都有能力處理請求。每個NODE都知道每個文檔所在的位置因此能夠直接將請求路由過去。下面的例子,咱們將全部的請求都發送到NODE1。