Elasticsearch 是一個免費的、分散式的、RESTful 風格的全文檢索引擎,它基於 Apache Lucene 開發而成。不僅支持全文檢索,還具有分散式和高可用性的特點,使其成為大規模數據檢索和分析的理想選擇。以下是主要特點:
Apache Lucene: 用於全文檢索和搜尋的開放原始碼程式庫
全文檢索引擎是一種專門用於在大量文本數據中快速查找特定關鍵字或短語的軟件。通過建立索引和使用高效的檢索算法,全文檢索引擎可以在短時間內返回與查詢條件相匹配的結果。全文檢索引擎在各種應用場景中都有廣泛的用途,例如:
Elasticsearch 使用一種名為倒序索引(Inverted Index)的數據結構來實現高效的全文檢索。倒序索引將文檔中的詞語與包含該詞語的文檔列表關聯起來,從而在檢索時能夠快速找到包含特定詞語的文檔。
概念 | Elasticsearch | Solr |
---|---|---|
索引數據的單位 | Index | Core |
文檔結構描述 | Mapping | Schema |
查詢語法 | Query DSL | Solr Query |
儲存數據的最小單位 | Document | Document |
儲存單位 | Shard | Shard |
儲存單位拷貝 | Replica | Replica |
文檔中的字段 | Field | Field |
分析器 | Analyzer | Analyzer |
篩選器 | Filter | Filter |
作業系統: Debian 9
JAVA版本: 7.x 建議是 JAVA 11
每個 elasticsearch 版本,搭配可支援的作業系統跟 JAVA版本。詳細的版本支援
常用檔案位置
Name | Path |
---|---|
基本設定檔 | /etc/elasticsearch/elasticsearch.yml |
jvm 設定檔 | /etc/elasticsearch/jvm.options |
plugin 執行檔 | /usr/share/elasticsearch/bin/elasticsearch-plugin |
elasticsearch.yml
cluster.name
: 群集名稱,節點會加入相同名稱的群集cluster.initial_master_nodes
:用於指定集群的初始主節點。node.name
: 節點名稱,方便區別不同的節點http.port
:服務的 HTTP 端口。默認值是 9200。path.data
: 索引儲存的路徑path.logs
: 日誌儲存的路徑node.master
: 是否為主節點node.data
: 是否為資料節點node.ingest
: 是否為預處理節點 (預設為 true)jvm.options
一個節點可以是包含一至多個節點角色
主節點(master node):主節點用於管理索引和集群級別的操作,如創建、刪除索引、節點加入或退出集群等。每個集群只能有一個主節點,如果主節點出現故障,集群將自動重新選舉新的主節點。
node.master: true
資料節點(data node):資料節點用於存儲索引資料和執行 CRUD(創建、讀取、更新、刪除)操作。資料節點負責維護索引的完整性和一致性,並將資料分片存儲在本地硬碟上。一個集群可以有多個資料節點,資料節點之間可以相互複製和同步資料。
node.data: true
預處理節點 (Ingest node): 在資料被索引之前,對資料進行預處理和轉換。各種資料轉換操作,包括資料格式轉換、資料清洗、資料修剪、資料解析等。
node.ingest: true
協調節點(coordinating node):協調節點用於處理請求和協調集群中的操作。它不存儲資料,而是充當請求路由器和負載均衡器的角色。協調節點接收來自客戶端的請求,並將請求路由到相應的資料節點上進行處理,然後將結果返回給客戶端。
node.master: false
node.data: false
如果是在 Google Compute Engine 內安裝 Elasticsearch,可以使用 discovery-gce 插件,這插件可以自動搜尋在同一個 GCP 專案內的 GCE 機器的群集加入,以下是需要在 elasticsearch.yml
增加的欄位。
如果需要將索引備份到 Google Cloud Storage 內,可以使用 repository-gce 插件。
適用於中文文本的 Elasticsearch 分析器,透過結合 IK 中文分詞器的分詞能力,對中文文本進行詞法分析,以實現更加精準的搜索。
ik_analyzer 可以對中文文本進行以下處理:
需要在 Elasticsearch 內安裝,如果有多台機器則需要在每個機器上皆安裝,各機器內的字典檔也必須同步。Elasticsearch 與 ik_analyzer 須搭配相同版本。實際的安裝方式可以參考官方的網頁的說明
由於是基於字典的分詞方式,所以有個合適的字典也是很重要的。除了可以先將自訂字典檔載入,還可以利用即時的線上字典,更新原有的字典檔。此方法不需要再重新啟動 Elasticsearch。只是要注意,字典檔只對,新的文本有效,對過去已索引的資料,並不會重新針對新的字典檔重新索引。如果要更新現有的資料,必須要手動重新索引資料。
(字典放置於 Google Cloud Storage 中,利用公開的網址存取)
IKAnalyzer.cfg.xml
內可以設定字典位置,
ext_dict
: 擴充字典檔位置,ext_stopwords
: 擴充停用詞字典檔位置remote_ext_dict
: 可設定外部線上字典,更新的方式是每 60 秒會利用 HEAD Trigger 連結,確認 header 內的 Last-Modified
或是 ETag
有沒有變化。如果有,就會 GET 方法,取得最新的字典檔,並重新更新現有的字典檔。更新 IKAnalyzer.cfg.xml
內容後,需要重新啟動 Elasticsearch 才能啟用。
配置檔案內容範例如下:
GET /_cat/plugins
IK analyzer 有提供兩種不同的分詞方法,分別為 ik_max_word
和 ik_smart
。
觀光
、官方網站
、官方
、網站
觀光
、官方網站
三個部分可做調整,對系統的設定(settings)、欄位名稱對映的類型(mappings)、別名設定(aliases)。
fielddata: 是否允許 Elasticsearch 將該欄位的值載入到記憶體中,以便在搜索過程中快速存取和處理該欄位的值。
是一種將文件中的欄位值載入到記憶體中以便搜索的資料結構。它允許 Elasticsearch 在搜索過程中快速存取和處理欄位資料,以提高搜索效能。
當我們執行某些類型的查詢時,Elasticsearch 需要在索引中載入欄位資料,例如聚合(aggregation)、排序、腳本腳本和文字查詢(text query)。這些查詢需要快速存取和處理欄位資料,以便在搜索結果中對文件進行排序或聚合。
為了實現這個目的,Elasticsearch 使用 fielddata 結構將欄位資料載入到記憶體中,使得搜索過程更快速、更高效。fielddata 結構被設計為緊湊的記憶體結構,可以減少磁碟 I/O 操作,從而提高查詢效能。
需要注意的是,由於 fielddata 需要將欄位值載入到記憶體中,因此它可能會佔用大量的記憶體。如果使用不當,fielddata 可能會導致節點記憶體不足或者效能下降。因此,在使用 Elasticsearch 時,應該謹慎使用 fielddata,並根據實際情況進行優化和調整。
PUT /<INDEX_NAME>
預先定義好的模板,用於自動設置新建的索引的設定、映射、別名。當新建一個索引時,如果索引名稱有相對應的模板,模板會自動應用到新的索引上。確保新的索引跟舊的索引有一致性。
PUT /_index_template/<TEMPLATE_NAME>
query_string: 複雜語法搜尋,針對一個或多個欄位進行全文檢索
title
有 台電
,且 content
中有出現 電廠
的文檔
term: 字段搜尋,此搜尋是不會針對字段分詞,需要精准匹配。
tags
內有 機場
的文檔
tags
內有 機場
或 桃園
的文檔
range:
publish_date
在 2022-01-01
到 2022-12-31
的文檔,包含前後兩天。
Boolean
用於組合多個查詢條件的查詢類型。通過 bool 查詢,可以將多個查詢子句以布林邏輯(例如 AND、OR、NOT)進行組合,從而實現更複雜的查詢需求。bool 查詢中包含四種子句類型
以下的範例是搜尋,必須包含 Elasticsearch
關鍵字在標題中且 status
不是 draft
,且至少包含 分散式
或 全文檢索
在內文中,且publish_date
在 2022-01-01
到 2022-12-31
間。
Aggregations
針對搜尋的結果進行聚合操作,計算統計數據。
以下的範例是使用 terms 聚合對文檔的 category 字段進行分組。將回傳每個狀態下的文檔數量。
用來對符合特定條件的所有文件進行更新,
用來刪除符合特定條件的所有文件,可搭配搜尋語法使用
使用時,有幾點需要注意:
是用於索引的邏輯名稱,可以用來替代實際的索引名。別名的使用具有許多優點和應用場景:
簡化操作:可以為複雜的、多索引的查詢操作創建一個別名,然後在後續的操作中只需要使用這個別名即可。
零停機時間的重建索引:當你需要改變索引的映射或者其他設置並且重建索引時,你可以創建一個新的索引,然後將別名從舊的索引移動到新的索引上,這樣不會影響正在使用別名的客戶端的操作。
時間序列數據:對於時間序列數據,你可以為每個時間週期(例如每天或者每月)創建一個新的索引,然後使用別名來代表所有的索引。這樣,你可以在不改變查詢代碼的情況下,輕鬆地添加新的索引和刪除舊的索引。
當群集內,有未分配的 分片分配不均的問題,使用此 API 可以解釋該分片為什麼會在目前的分配狀態。
以下範例,myindex
是索引的名稱,0
是我們想要解釋的分片號碼,primary
表示我們正在解釋主分片。
這個請求將返回一個詳細解釋,說明該分片是否被分配,如果沒有被分配,為什麼沒有被分配,如果已經被分配,它是如何被分配的。
手動將分片從一個節點移動到另一個節點。
在這個例子中,myindex 的 0號分片將從nodeA移動到nodeB。