Elasticsearch 是一個開源的、基于 Lucene 的分布式搜索和分析引擎,設(shè)計用于云計算環(huán)境中,能夠?qū)崿F(xiàn)實時的、可擴展的搜索、分析和探索全文和結(jié)構(gòu)化數(shù)據(jù)。它具有高度的可擴展性,可以在短時間內(nèi)搜索和分析大量數(shù)據(jù)。
Elasticsearch 不僅僅是一個全文搜索引擎,它還提供了分布式的多用戶能力,實時的分析,以及對復雜搜索語句的處理能力,使其在眾多場景下,如企業(yè)搜索,日志和事件數(shù)據(jù)分析等,都有廣泛的應用。
本文將向你詳細介紹什么是倒排索引、以及 Elasticsearch 查詢、相關(guān)性評分和搜索優(yōu)化的相關(guān)原理。
1、倒排索引
1.1、為什么需要倒排索引
倒排索引,也是索引。索引,初衷都是為了快速檢索到你要的數(shù)據(jù)。
每種數(shù)據(jù)庫都有自己要解決的問題(或者說擅長的領(lǐng)域),對應的就有自己的數(shù)據(jù)結(jié)構(gòu),而不同的使用場景和數(shù)據(jù)結(jié)構(gòu),需要用不同的索引,才能起到最大化加快查詢的目的。
對 Mysql 來說,是 B+ 樹,對 Elasticsearch 和 Lucene 來說,是倒排索引。
Elasticsearch 是建立在全文搜索引擎庫 Lucene 基礎(chǔ)上的搜索引擎,它隱藏了 Lucene 的復雜性,取而代之的提供一套簡單一致的 RESTful API,不過掩蓋不了它底層也是 Lucene 的事實。Elasticsearch 的倒排索引,其實就是 Lucene 的倒排索引。
1.2、為什么叫倒排索引
“倒排索引”(Inverted Index)的概念是從"正向索引"(Forward Index)中衍生出來的。
在"正向索引"中,我們從文檔出發(fā),記錄下每個文檔中出現(xiàn)的詞項,這樣就可以知道每個文檔包含哪些詞項。而在"倒排索引"中,我們從詞項出發(fā),記錄下每個詞項出現(xiàn)在哪些文檔中,這樣就可以知道每個詞項被哪些文檔包含。
正向索引:document -> to -> words
倒排索引:word -> to -> documents
因此,“倒排索引"可以看作是"正向索引"的逆操作,所以被稱為"倒排”。在全文搜索中,"倒排索引"是非常重要的數(shù)據(jù)結(jié)構(gòu),因為它可以讓我們快速找到包含特定詞項的所有文檔。
1.3、倒排索引的結(jié)構(gòu)
倒排索引作為一種數(shù)據(jù)結(jié)構(gòu),用于存儲一種映射關(guān)系,即從詞項到出現(xiàn)該詞項的文檔的映射。它是全文搜索引擎的核心組成部分,如 Elasticsearch、Lucene 等。
在倒排索引中,每個唯一的詞項都有一個相關(guān)的倒排列表,這個列表中包含了所有包含該詞項的文檔的 ID。這樣,當我們搜索一個詞項時,搜索引擎只需要查找倒排索引,就可以快速找到所有包含這個詞項的文檔。
例如,假設(shè)我們有以下三個文檔:
1. 文檔1:I love coding
2. 文檔2:I love reading
3. 文檔3:I love both
對這些文檔建立倒排索引后,我們會得到以下的映射關(guān)系:
- I:文檔1,文檔2,文檔3
- love:文檔1,文檔2,文檔3
- coding:文檔1
- reading:文檔2
- both:文檔3
所以,當我們搜索"love"時,搜索引擎會在倒排索引中找到"love",然后返回所有包含"love"的文檔,即文檔1,文檔2 和文檔3。
2、數(shù)據(jù)查詢過程
2.1、數(shù)據(jù)查詢處理原理
在 Elasticsearch 中,查詢處理主要包括以下步驟:
- 解析查詢語句:首先,Elasticsearch 會解析用戶的查詢請求,將其轉(zhuǎn)換為內(nèi)部的查詢表示。這個過程包括解析查詢語句的語法、解析查詢參數(shù)、驗證查詢語句的合法性等。
- 生成查詢計劃:解析查詢語句后,Elasticsearch 會生成一個查詢計劃。查詢計劃描述了如何在倒排索引上執(zhí)行查詢,包括哪些詞項需要查詢、如何組合詞項的查詢結(jié)果等。
- 執(zhí)行查詢:有了查詢計劃后,Elasticsearch 就可以在倒排索引上執(zhí)行查詢了。這個過程包括查找詞項的倒排列表、計算文檔和查詢的相關(guān)性、生成候選結(jié)果集等。
- 生成查詢結(jié)果:最后,Elasticsearch 會根據(jù)候選結(jié)果集和查詢參數(shù),生成最終的查詢結(jié)果。這個過程包括排序候選結(jié)果、生成摘要、分頁等。
2.2、解析查詢語句
在 Elasticsearch 中,解析查詢語句是查詢處理的第一步。這個過程主要包括以下步驟:
- 解析 JSON:Elasticsearch 的查詢語句通常以 JSON 格式提供。首先,Elasticsearch 會解析 JSON,將其轉(zhuǎn)換為內(nèi)部的數(shù)據(jù)結(jié)構(gòu)。
{
"query": {
"match": {
"field_name": "query_value"
}
}
}
- 解析查詢類型:查詢語句中通常會指定查詢類型(包括 Match 查詢用于基本的全文搜索,Term 查詢用于精確匹配,Range 查詢用于范圍搜索,Bool 查詢用于邏輯組合多個查詢條件,Phrase 查詢用于短語搜索,Wildcard 查詢用于通配符搜索,Prefix 查詢用于前綴搜索,以及 Fuzzy 查詢用于模糊搜索等)。Elasticsearch 會解析查詢類型,并根據(jù)查詢類型選擇相應的查詢處理器。
- 解析查詢參數(shù):查詢語句中還會包含一些查詢參數(shù),如字段名、查詢值、模糊匹配的閾值等。Elasticsearch 會解析這些查詢參數(shù),并將它們傳遞給查詢處理器。
- 驗證查詢語句:最后,Elasticsearch 會驗證查詢語句的合法性。例如,檢查字段名是否存在,檢查查詢值的類型是否與字段類型匹配等。如果查詢語句不合法,Elasticsearch 會返回一個錯誤。
2.3、生成查詢計劃
在 Elasticsearch 中,生成查詢計劃的過程包括確定查詢類型(如 match
、term
、range
等),確定要查詢的字段和值,然后根據(jù)這些信息生成查詢計劃,描述了如何在倒排索引上執(zhí)行查詢,包括哪些詞項需要查詢以及如何組合詞項的查詢結(jié)果。
2.4、執(zhí)行查詢
在 Elasticsearch 中,執(zhí)行查詢是查詢處理過程的關(guān)鍵步驟。這個過程主要包括以下步驟:
-
查找詞項:根據(jù)查詢計劃,Elasticsearch 會在倒排索引中查找每個詞項的倒排列表。
-
計算相關(guān)性:Elasticsearch 會計算每個文檔和查詢的相關(guān)性。這通常通過一個名為 TF-IDF 的算法來完成。
-
生成候選結(jié)果集:Elasticsearch 會根據(jù)相關(guān)性的計算結(jié)果,生成一個候選結(jié)果集。這個結(jié)果集包含了所有可能滿足查詢條件的文檔。
2.5、生成查詢結(jié)果
在 Elasticsearch 中,生成查詢結(jié)果是查詢處理過程的最后一步。這個過程主要包括以下步驟:
-
排序:Elasticsearch 會根據(jù)每個文檔和查詢的相關(guān)性,對候選結(jié)果集進行排序。
-
生成摘要:為了方便用戶查看查詢結(jié)果,Elasticsearch 會為每個文檔生成一個摘要。摘要通常包括文檔的一部分內(nèi)容和查詢詞項的位置。
-
分頁:如果查詢請求中指定了分頁參數(shù),Elasticsearch 會根據(jù)這些參數(shù),從排序后的結(jié)果集中提取出一個頁面的結(jié)果。
-
返回結(jié)果:最后,Elasticsearch 會將查詢結(jié)果返回給用戶。查詢結(jié)果通常以 JSON 格式提供,包括總的命中數(shù)、查詢時間、每個文檔的 ID、摘要等信息。
以上就是 Elasticsearch 生成查詢結(jié)果的基本過程。需要注意的是,這個過程可能會受到查詢語句的復雜性、數(shù)據(jù)量的大小、集群的狀態(tài)等因素的影響。
3、相關(guān)性評分
3.1、相關(guān)性評分的作用
在 Elasticsearch 中,相關(guān)性評分(也稱為評分或得分)是用來衡量一個文檔與查詢條件的匹配程度的。它是由 Elasticsearch 的查詢模塊根據(jù) TF-IDF 算法或其他相關(guān)性算法計算出來的一個數(shù)值。
相關(guān)性評分的作用主要體現(xiàn)在以下幾個方面:
-
排序:在返回查詢結(jié)果時,Elasticsearch 會根據(jù)相關(guān)性評分對結(jié)果進行排序。評分越高的文檔,被認為與查詢條件的匹配程度越高,因此會被排在更前面。****
-
篩選:在某些情況下,你可能只關(guān)心那些與查詢條件高度匹配的文檔。這時,你可以設(shè)置一個評分閾值,只返回評分高于這個閾值的文檔。
-
調(diào)優(yōu):通過理解和調(diào)整相關(guān)性評分的計算方式,你可以優(yōu)化查詢的效果,使其更符合你的需求。例如,你可以通過設(shè)置字段的權(quán)重,影響其在評分計算中的重要性。
需要注意的是,相關(guān)性評分并不是一個絕對的值,它的大小并不能直接反映出文檔的質(zhì)量或重要性。它只是表示了文檔與特定查詢條件的匹配程度。同一個文檔對于不同的查詢條件,可能會有不同的評分。
3.2、TF-IDF 原理
TF-IDF(詞頻-逆文檔頻率)算法用于評估一個詞對于一個文件集或語料庫中的某個文件的重要程度。它的工作原理如下:
-
Term Frequency (TF):衡量一個詞在文檔中出現(xiàn)的頻率。計算方法通常是將文檔中某個詞出現(xiàn)的次數(shù)除以文檔中所有詞的總數(shù)。TF 值越高,表示該詞在文檔中的重要性越高。
-
Inverse Document Frequency (IDF):衡量一個詞是否常見。計算方法是將語料庫中的文檔總數(shù)除以包含該詞的文檔數(shù)的對數(shù)。IDF 值越高,表示該詞的信息量越大,對于區(qū)分文檔的重要性越高。
-
TF-IDF 值計算:將 TF 值和 IDF 值相乘,得到最終的 TF-IDF 值。TF-IDF 值越高,表示該詞對于某個文檔的重要性越高。
在 Elasticsearch 中,對于每個查詢詞,會計算它在文檔中的 TF 值和在整個語料庫中的 IDF 值,然后將這兩個值相乘,得到最終的 TF-IDF 值。查詢結(jié)果按照 TF-IDF 值的大小進行排序,TF-IDF 值越大,表示文檔和查詢的相關(guān)性越高。
TF-IDF 算法的目標是通過考慮詞頻和詞的普遍性來確定詞的重要性,從而提高信息檢索的準確性和相關(guān)性。
3.3、其他評分規(guī)則
除了基于 TF-IDF 的相關(guān)性評分外,Elasticsearch 還提供了其他的評分規(guī)則,以滿足不同的搜索需求。以下是一些常見的評分規(guī)則:
- Constant Score:這種評分規(guī)則會給所有的文檔賦予相同的評分。它通常用于過濾操作,因為在過濾操作中,我們只關(guān)心文檔是否滿足條件,而不關(guān)心文檔的相關(guān)性。
- Boolean/Disjunction Max Score:這種評分規(guī)則會計算每個查詢條件的評分,然后取最高的評分作為最終的評分。它通常用于多條件查詢,因為在多條件查詢中,我們通常關(guān)心的是文檔滿足任何一個條件的程度。
- Function Score:這種評分規(guī)則允許你自定義評分函數(shù),以實現(xiàn)復雜的評分邏輯。你可以基于文檔的字段值、查詢參數(shù)、腳本等因素,計算出一個評分。
以上只是 Elasticsearch 評分規(guī)則的一部分,實際上 Elasticsearch 還提供了更多的評分規(guī)則,如 script_score
、field_value_factor
、decay functions
等,可以滿足各種復雜的搜索需求。
4、搜索功能
Elasticsearch 提供了一些高級搜索功能,如全文搜索、模糊搜索、范圍搜索、聚合搜索等。
4.1、全文搜索
Elasticsearch 最基本且核心的功能就是全文搜索。全文搜索是指對大量文本數(shù)據(jù)進行搜索,找出包含指定詞項的文檔。Elasticsearch 使用倒排索引這種數(shù)據(jù)結(jié)構(gòu)來實現(xiàn)高效的全文搜索。
全文搜索的工作原理主要基于倒排索引。倒排索引是一種數(shù)據(jù)結(jié)構(gòu),它將所有的詞項(Term)映射到出現(xiàn)這些詞項的文檔列表。當執(zhí)行全文搜索時,Elasticsearch 會根據(jù)查詢的詞項找到對應的文檔列表,然后根據(jù)一定的評分規(guī)則(如 TF-IDF)計算每個文檔的相關(guān)性得分,并按得分排序返回結(jié)果。
Elasticsearch 的全文搜索支持多種查詢類型,如 match
查詢、multi_match
查詢、query_string
查詢等。這些查詢類型可以滿足各種復雜的搜索需求,如單詞搜索、短語搜索、布爾搜索等。
4.2、多值搜索
在 Elasticsearch 中,如果你需要對多個值進行搜索,可以使用 terms
查詢。terms
查詢允許你指定一個字段和多個值,Elasticsearch 會返回所有字段值在這些值中的文檔。
terms
查詢的工作原理是將每個值都轉(zhuǎn)換為一個 term
查詢,然后將這些 term
查詢以 OR
的方式進行組合。這意味著只要文檔的字段值匹配了任何一個值,就會被認為滿足查詢條件。
例如,如果你執(zhí)行一個 terms
查詢,查找顏色為 “紅色” 或 “藍色” 的商品,Elasticsearch 會首先在倒排索引中查找 “紅色” 和 “藍色” 這兩個詞項的倒排列表,然后將這兩個列表進行合并,得到最終的結(jié)果。
需要注意的是,terms
查詢只適用于精確值的匹配,不適用于全文搜索。如果你需要對多個詞項進行全文搜索,可以使用 multi_match
查詢或 query_string
查詢。
4.3、模糊搜索
Elasticsearch 的模糊搜索是一種能夠處理拼寫錯誤和近似搜索的功能。
模糊搜索的實現(xiàn)主要基于編輯距離(Levenshtein distance)算法,該算法可以計算兩個詞項之間的差異程度。編輯距離是通過計算從一個詞項變換到另一個詞項所需的最少單字符編輯操作(如插入、刪除、替換)的數(shù)量來衡量差異程度。
在 Elasticsearch 中,可以使用 fuzzy
查詢來進行模糊搜索。fuzzy
查詢允許你指定一個 fuzziness
參數(shù),該參數(shù)決定了允許的最大編輯距離。例如,fuzziness
參數(shù)設(shè)置為 1,那么就可以匹配出與查詢詞項編輯距離在 1 以內(nèi)的所有詞項。
模糊搜索非常適合處理用戶輸入錯誤的情況,可以提高搜索的容錯性,從而提升用戶體驗。
4.4、范圍搜索
Elasticsearch 的范圍搜索允許你查找字段值在指定范圍內(nèi)的文檔。
范圍搜索在 Elasticsearch 中主要通過 range
查詢來實現(xiàn)。在 range
查詢中,你可以為字段指定一個上界和一個下界,Elasticsearch 會返回所有字段值在這個范圍內(nèi)的文檔。
例如,你可以查找價格在 10 到 20 之間的所有商品,或者查找發(fā)布日期在過去一周內(nèi)的所有文章。
range
查詢支持數(shù)值字段、日期字段、IP 地址字段等多種類型的字段。對于日期字段,你還可以使用日期數(shù)學表達式來指定范圍,如 now-1d
表示從現(xiàn)在開始的過去一天。
此外,range
查詢還支持開閉區(qū)間的設(shè)置,你可以通過 gte
(大于等于)、gt
(大于)、lte
(小于等于)、lt
(小于)等參數(shù)來控制區(qū)間的開閉。
范圍搜索是 Elasticsearch 中非常常用的一種搜索方式,它可以滿足各種基于范圍的過濾和查詢需求。
4.5、聚合搜索
Elasticsearch 的聚合搜索是一種強大的數(shù)據(jù)分析工具,它允許你在搜索結(jié)果上進行各種統(tǒng)計分析。
聚合搜索在 Elasticsearch 中主要通過聚合(Aggregations)功能來實現(xiàn)。聚合功能提供了一組用于數(shù)據(jù)分析的操作符,如 min
、max
、avg
、sum
、count
等,你可以使用這些操作符來對搜索結(jié)果進行統(tǒng)計分析。
例如,你可以使用 avg
聚合來計算所有商品的平均價格,或者使用 histogram
聚合來統(tǒng)計每個價格區(qū)間的商品數(shù)量。
此外,聚合功能還支持嵌套聚合,你可以在一個聚合的基礎(chǔ)上進行另一個聚合。這使得你可以實現(xiàn)復雜的數(shù)據(jù)分析需求,如分組統(tǒng)計、多級分組統(tǒng)計等。
聚合搜索是 Elasticsearch 中非常強大的一種功能,它可以滿足各種復雜的數(shù)據(jù)分析需求。
5、搜索優(yōu)化
5.1、索引優(yōu)化
在 Elasticsearch 中,優(yōu)化索引結(jié)構(gòu)是提高搜索性能的重要手段。以下是一些常見的索引優(yōu)化策略:
-
合理設(shè)置分片數(shù)量:每個索引都可以分為多個分片,每個分片是索引數(shù)據(jù)的一個獨立部分。分片的數(shù)量會影響 Elasticsearch 的并行處理能力,但是過多的分片會增加集群的管理負擔,可能會降低性能。因此,需要根據(jù)數(shù)據(jù)量、硬件資源等因素,合理設(shè)置分片的數(shù)量。
-
使用合適的字段類型:Elasticsearch 支持多種字段類型,不同的字段類型有不同的索引和搜索性能。例如,對于需要全文搜索的字段,應該使用
text
類型,因為text
類型會對字段值進行分詞處理,適合全文搜索;對于需要精確匹配的字段,應該使用keyword
類型,因為keyword
類型不會對字段值進行分詞處理,適合精確匹配。 -
禁用不需要搜索的字段的索引:如果一個字段不需要被搜索,那么就沒有必要為它建立索引。你可以在映射中將這個字段的
index
參數(shù)設(shè)置為false
,這樣 Elasticsearch 就不會為這個字段建立索引,可以節(jié)省存儲空間,提高索引和搜索性能。 -
優(yōu)化文檔結(jié)構(gòu):盡量避免使用嵌套類型(nested type),因為嵌套類型會增加索引的復雜性和存儲開銷。如果需要在數(shù)組字段上進行搜索,可以考慮使用
flattened
類型。
以上只是優(yōu)化 Elasticsearch 索引結(jié)構(gòu)的一部分方法,實際上還有很多其他的優(yōu)化技術(shù)和策略,如使用 doc_values
優(yōu)化排序和聚合、使用 routing
優(yōu)化分片訪問等。
5.2、查詢優(yōu)化
在 Elasticsearch 中,優(yōu)化查詢語句是提高搜索性能的重要手段。以下是一些常見的查詢優(yōu)化策略:
-
避免使用高開銷的查詢:某些類型的查詢,如
wildcard
、regexp
、fuzzy
等,由于需要對大量的詞項進行匹配,所以開銷較大。在性能敏感的場景下,應盡量避免使用這些查詢。 -
優(yōu)先使用 filter:在 Elasticsearch 中,
filter
和query
都可以用來過濾文檔,但是filter
的結(jié)果可以被緩存,下次執(zhí)行相同的filter
時可以直接使用緩存,從而提高性能。因此,對于那些不需要計算相關(guān)性得分的過濾條件,應優(yōu)先使用filter
。 -
避免深度分頁:深度分頁指的是獲取結(jié)果的后面幾頁,如第 1000 頁。深度分頁需要 Elasticsearch 對前面所有的結(jié)果進行排序,開銷較大。如果需要處理大量的結(jié)果,應考慮使用
scroll
API 或search_after
參數(shù)。 -
減少返回的字段:默認情況下,Elasticsearch 會返回文檔的所有字段。如果只需要文檔的部分字段,可以使用
_source
參數(shù)來指定返回的字段,這樣可以減少網(wǎng)絡(luò)傳輸?shù)臄?shù)據(jù)量,提高性能。
以上只是優(yōu)化 Elasticsearch 查詢語句的一部分方法,實際上還有很多其他的優(yōu)化技術(shù)和策略,如使用 bool
查詢的 must
、should
、filter
、must_not
來優(yōu)化布爾邏輯,使用 constant_score
查詢來優(yōu)化靜態(tài)得分等。
5.3、使用doc_values優(yōu)化排序和聚合
在 Elasticsearch 中,doc_values
是一種在磁盤上的列式存儲,它可以用來快速、高效地執(zhí)行排序、聚合等操作。
當你對一個字段進行排序或聚合時,Elasticsearch 需要訪問該字段的所有值。如果這些值存儲在文檔中,那么 Elasticsearch 就需要從磁盤中加載每個文檔,這可能會非常慢。而 doc_values
則將字段的值存儲在磁盤的一個單獨的區(qū)域,Elasticsearch 可以直接訪問這些值,無需加載文檔,因此可以大大提高性能。
默認情況下,Elasticsearch 會為所有的 keyword
類型和數(shù)值類型的字段啟用 doc_values
。如果你有一個 text
類型的字段,也需要進行排序或聚合,那么你可以為該字段添加一個 keyword
類型的子字段,并啟用 doc_values
。
需要注意的是,雖然 doc_values
可以提高排序和聚合的性能,但它也會占用額外的磁盤空間。因此,對于不需要排序或聚合的字段,你可以在映射中將 doc_values
設(shè)置為 false
,以節(jié)省磁盤空間。
5.4、使用routing優(yōu)化分片
在 Elasticsearch 中,routing
參數(shù)可以用來控制文檔存儲到哪個分片,以及搜索請求路由到哪個分片。通過合理的路由策略,可以顯著提高搜索性能。
默認情況下,Elasticsearch 會根據(jù)文檔的 ID 來決定將文檔存儲到哪個分片,搜索請求會路由到所有的分片。這種策略可以保證數(shù)據(jù)的均勻分布,但在某些情況下,可能并不高效。
例如,如果你的索引包含了多個用戶的數(shù)據(jù),每次搜索請求只涉及到一個用戶的數(shù)據(jù),那么默認的路由策略就會導致很多無效的搜索,因為大部分分片并不包含該用戶的數(shù)據(jù)。
這時,你可以使用 routing
參數(shù)來優(yōu)化分片訪問。你可以將用戶 ID 作為 routing
參數(shù)的值,這樣同一個用戶的所有文檔就會被存儲到同一個分片,搜索請求也只會路由到該分片。這樣可以大大減少無效的搜索,提高搜索性能。
需要注意的是,雖然 routing
參數(shù)可以提高搜索性能,但如果使用不當,也可能導致數(shù)據(jù)分布不均,影響集群的穩(wěn)定性。因此,在使用 routing
參數(shù)時,需要充分考慮數(shù)據(jù)的分布情況。文章來源:http://www.zghlxwxcb.cn/news/detail-713239.html
5.5、其他優(yōu)化
除上述兩種,還可以考慮:文章來源地址http://www.zghlxwxcb.cn/news/detail-713239.html
- 使用緩存:Elasticsearch 提供了查詢結(jié)果緩存和字段數(shù)據(jù)緩存,可以提高重復查詢的性能。需要注意的是,緩存并不總是有益的,如果查詢模式具有很高的隨機性,緩存可能會降低性能。
- 硬件優(yōu)化:提升硬件性能也可以提高搜索性能,如增加內(nèi)存可以提高緩存效果,使用 SSD 可以提高 IO 性能等。
到了這里,關(guān)于Elasticsearch數(shù)據(jù)搜索原理的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!