Elasticsearch 核心原理介紹

1、Elasticsearch 是什么?

Elasticsearch 是一個基于 Lucene 構(gòu)建的、開源的、分布式的、RESTful 的搜索和分析引擎。

  • 基于 Lucene: 它的底層核心是 Apache Lucene,一個強(qiáng)大、高性能的 Java 搜索引擎庫。Elasticsearch 在 Lucene 的基礎(chǔ)上,提供了更簡單易用的功能和分布式架構(gòu)。
  • 分布式: 數(shù)據(jù)可以被分片并分布到集群中的多個節(jié)點(diǎn)上,這使得它能夠處理海量數(shù)據(jù)(PB級別),并提供高可用性和強(qiáng)大的橫向擴(kuò)展能力。
  • 搜索和分析引擎: 它不僅用于傳統(tǒng)的全文檢索,還非常擅長進(jìn)行復(fù)雜的數(shù)據(jù)分析,例如聚合操作(Aggregation),可以生成復(fù)雜的報表和指標(biāo)。

常見應(yīng)用場景:

  • 網(wǎng)站搜索: 電商網(wǎng)站的商品搜索、新聞網(wǎng)站的文章搜索。
  • 日志數(shù)據(jù)分析 (ELK Stack): 與 Logstash 和 Kibana 組成 ELK 棧,用于收集、存儲、分析和可視化日志數(shù)據(jù),是運(yùn)維和開發(fā)的利器。
  • 應(yīng)用性能監(jiān)控 (APM): 追蹤應(yīng)用程序的性能問題。
  • 企業(yè)搜索: 搜索公司內(nèi)部的各種文檔、郵件、數(shù)據(jù)。

2、核心原理介紹

2.1、分詞

分詞 是將一段文本切分成一個個獨(dú)立的、有意義的詞條的過程。它是文本處理和搜索的基礎(chǔ)。例如:

輸入: "我愛北京天安門"
輸出: ["我", "愛", "北京", "天安門"]  # 智能分詞

分詞過程通常包括以下步驟:

  • 字符過濾:使用字符過濾器(Character Filter)對原始文本進(jìn)行預(yù)處理,例如去除HTML標(biāo)簽、替換特殊字符等。
  • 分詞:使用分詞器(Tokenizer)將文本拆分成單個的詞條(tokens)。例如,標(biāo)準(zhǔn)分詞器會根據(jù)空格和標(biāo)點(diǎn)將文本分成多個詞條。
  • 詞條過濾:使用詞條過濾器(Token Filter)對分詞后的結(jié)果進(jìn)行進(jìn)一步處理,例如轉(zhuǎn)為小寫、刪除停用詞、添加同義詞等。
原始文本
     ↓
字符過濾器(如:去除HTML標(biāo)簽)
     ↓
分詞器(按規(guī)則切分)
     ↓
詞條過濾器(如:轉(zhuǎn)小寫、去停用詞)
     ↓
最終詞條

2.2、核心原理:倒排索引

這是 Elasticsearch 能夠?qū)崿F(xiàn)快速全文搜索的基石。

傳統(tǒng)數(shù)據(jù)庫的困境:如果想在內(nèi)容字段中搜索包含“搜索”的記錄,傳統(tǒng)數(shù)據(jù)庫會使用 LIKE ‘%搜索%’,這會導(dǎo)致全表掃描,效率極低。

傳統(tǒng)數(shù)據(jù)庫使用正排索引(文檔 → 詞條),而 Elasticsearch 使用倒排索引(詞條 → 文檔)。

假設(shè)有三個文檔:

  • 文檔1:"蘋果公司發(fā)布了新手機(jī)"
  • 文檔2:"這個蘋果很好吃"
  • 文檔3:"手機(jī)市場競爭激烈"

步驟1:文檔分詞

文檔1 → ["蘋果", "公司", "發(fā)布", "了", "新", "手機(jī)"]
文檔2 → ["這個", "蘋果", "很", "好吃"]  
文檔3 → ["手機(jī)", "市場", "競爭", "激烈"]

步驟2:標(biāo)準(zhǔn)化處理

  • 去除停用詞("了", "這個", "很"等)
  • 統(tǒng)一大小寫(如果有英文)
  • 詞干提?。ㄈ?發(fā)布了" → "發(fā)布")

步驟3:構(gòu)建倒排索引表

詞條 文檔ID列表 位置信息 其他元數(shù)據(jù)
蘋果 [1, 2] 1:[0], 2:[1] {doc_freq: 2}
公司 [1] 1:[1] {doc_freq: 1}
發(fā)布 [1] 1:[2] {doc_freq: 1}
[1] 1:[4] {doc_freq: 1}
手機(jī) [1, 3] 1:[5], 3:[0] {doc_freq: 2}
好吃 [2] 2:[3] {doc_freq: 1}
市場 [3] 3:[1] {doc_freq: 1}
競爭 [3] 3:[2] {doc_freq: 1}
激烈 [3] 3:[3] {doc_freq: 1}

2.3、搜索執(zhí)行流程

例如我們需要搜索查詢:"蘋果手機(jī)"

步驟1:查詢解析與分詞
查詢字符串被分詞為:["蘋果", "手機(jī)"]

步驟2:查找倒排索引

  • 查找"蘋果" → 得到文檔列表 [1, 2]
  • 查找"手機(jī)" → 得到文檔列表 [1, 3]

步驟3:結(jié)果合并
對于布爾OR查詢(默認(rèn)):取并集 [1, 2, 3]
對于布爾AND查詢:取交集 [1]

步驟4:相關(guān)性評分(TF-IDF算法)

TF(詞頻)- 在單個文檔中的重要性:

  • 文檔1中:"蘋果"出現(xiàn)1次,"手機(jī)"出現(xiàn)1次
  • 文檔2中:"蘋果"出現(xiàn)1次,"手機(jī)"出現(xiàn)0次
  • 文檔3中:"蘋果"出現(xiàn)0次,"手機(jī)"出現(xiàn)1次

IDF(逆文檔頻率)- 在整個索引中的重要性:

  • "蘋果"的IDF = log(3/2) = 0.176 (3個總文檔,2個包含"蘋果")
  • "手機(jī)"的IDF = log(3/2) = 0.176 (3個總文檔,2個包含"手機(jī)")

計算得分:

文檔1得分 = TF("蘋果") × IDF("蘋果") + TF("手機(jī)") × IDF("手機(jī)")
         = 1 × 0.176 + 1 × 0.176 = 0.352
文檔2得分 = 1 × 0.176 + 0 × 0.176 = 0.176
文檔3得分 = 0 × 0.176 + 1 × 0.176 = 0.176

步驟5:結(jié)果排序和返回
按得分排序返回:

  1. 文檔1 (得分: 0.352)
  2. 文檔2 (得分: 0.176)
  3. 文檔3 (得分: 0.176)

這樣我們就找到了對應(yīng)的文檔,并可以按得分排序。


3、總結(jié)

3.1、索引構(gòu)建流程(數(shù)據(jù)準(zhǔn)備階段)
┌─────────────┐    ┌───────────────┐    ┌─────────────┐    ┌────────────────┐
│  輸入文本     │ -> │ 文本預(yù)處理     │ -> │   分詞       │ -> │ 構(gòu)建倒排索引     │
│             │    │               │    │             │    │                │
│ ? 文檔數(shù)據(jù)   │     │ ? 大小寫轉(zhuǎn)換   │    │ ? 中文分詞    │    │ ? 詞條→文檔映射 │
│ ? JSON格式   │    │ ? 去除HTML標(biāo)簽 │    │ ? 英文分詞    │    │ ? 位置信息記錄  │
│             │    │ ? 特殊字符處理  │    │ ? 停用詞過濾  │    │ ? 詞頻統(tǒng)計      │
└─────────────┘    └───────────────┘    └─────────────┘    └────────────────┘

示例:

輸入: "蘋果公司發(fā)布了新手機(jī)"
預(yù)處理: "蘋果公司發(fā)布了新手機(jī)"  
分詞: ["蘋果", "公司", "發(fā)布", "新", "手機(jī)"]
倒排索引: 
  "蘋果" → [文檔1]
  "手機(jī)" → [文檔1]
  "公司" → [文檔1]
  ...
3.2、搜索查詢流程(檢索階段)
┌─────────────┐    ┌─────────────┐    ┌────────────────┐    ┌─────────────┐    ┌────────────────┐
│  搜索查詢    │ -> │    分詞      │ -> │ 查找倒排索引     │ -> │  結(jié)果合并    │ -> │ 相關(guān)性評分       │
│             │    │             │    │                │    │             │    │                │
│ ? 用戶輸入   │    │ ? 查詢詞分詞  │    │ ? 多詞條并行查找 │    │ ? 集合運(yùn)算    │    │ ? TF-IDF/BM25  │
│ ? 查詢語法   │    │ ? 同義詞擴(kuò)展  │    │ ? 分布式分片查找 │    │ ? 去除重復(fù)    │    │ ? 位置加權(quán)      │
│             │    │             │    │                │    │             │    │ ? 字段權(quán)重      │
└─────────────┘    └─────────────┘    └────────────────┘    └─────────────┘    └────────────────┘

示例:

查詢: "蘋果 手機(jī)"
分詞: ["蘋果", "手機(jī)"]
查找: 
  "蘋果" → [文檔1, 文檔2]
  "手機(jī)" → [文檔1, 文檔3]
結(jié)果合并: [文檔1] (AND操作)
相關(guān)性評分: 文檔1得分最高(包含兩個詞條)
3.3、完整架構(gòu)視圖
      ┌─────────────────┐              ┌─────────────────┐
      │   索引構(gòu)建流程    │              │   搜索查詢流程    │
      │  (數(shù)據(jù)準(zhǔn)備)      │              │  (檢索執(zhí)行)       │
      ├─────────────────┤              ├─────────────────┤
      │ 輸入文本         │              │ 搜索查詢          │
      │       ↓         │              │       ↓         │
      │ 文本預(yù)處理        │              │ 分詞            │
      │       ↓         │              │       ↓         │
      │ 分詞             │              │ 查找倒排索引      │
      │       ↓         │              │       ↓         │
      │ 構(gòu)建倒排索引      │─────────────┤ 結(jié)果合并         │
      └─────────────────┘  依賴關(guān)系     │       ↓         │
                             │         │ 相關(guān)性評分        │
                             │         └─────────────────┘
                             │
                   ┌─────────┴─────────┐
                   │  倒排索引存儲       │
                   │  (核心數(shù)據(jù)結(jié)構(gòu))     │
                   │ ? 詞條詞典         │
                   │ ? 文檔列表         │
                   │ ? 位置信息         │
                   └───────────────────┘
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容