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 (得分: 0.352)
- 文檔2 (得分: 0.176)
- 文檔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)) │
│ ? 詞條詞典 │
│ ? 文檔列表 │
│ ? 位置信息 │
└───────────────────┘