ElasticSearch應(yīng)用篇-搜索效果

一、集群搜索問(wèn)題

1.問(wèn)題:如何聚合多個(gè)節(jié)點(diǎn)或分片的數(shù)據(jù)生成返回結(jié)果

在對(duì)Mysql進(jìn)行分庫(kù)分表的時(shí)候,經(jīng)常會(huì)遇到一個(gè)問(wèn)題:如果查詢的數(shù)據(jù)分散在多張表中,因?yàn)樯婕暗浇M合多種表的數(shù)據(jù),將會(huì)非常麻煩;對(duì)于有些分頁(yè)場(chǎng)景,更是一個(gè)災(zāi)難,所以對(duì)Mysql分庫(kù)分表的時(shí)候經(jīng)常會(huì)基于查詢維度來(lái)盡量避免跨表查詢的場(chǎng)景。

ElasticSearch也是分布式的,當(dāng)數(shù)據(jù)分散與多個(gè)節(jié)點(diǎn)或者分片上時(shí),他是如何解決數(shù)據(jù)聚合問(wèn)題的呢?另外,搜索基本都需要排序,如何解決排序問(wèn)題呢?

2.ES整體流程

假設(shè)有N個(gè)分片,數(shù)據(jù)可能分散在這N個(gè)分片上,ES搜索時(shí),整體操作過(guò)程是:

S1: 客戶端將會(huì)同時(shí)向N個(gè)分片發(fā)起搜索請(qǐng)求。

S2: 這N個(gè)分片基于本分片的內(nèi)容獨(dú)立完成搜索,然后將符合條件的結(jié)果全部返回。

S3: 客戶端將返回的結(jié)果進(jìn)行重新排序和排名,最后返回給用戶。

有經(jīng)驗(yàn)的開發(fā)很容易看出來(lái),這里有兩個(gè)問(wèn)題:

數(shù)量問(wèn)題。假設(shè)每次返回10條記錄,那么這N個(gè)分片獨(dú)立執(zhí)行查詢以后,每個(gè)分片最多都會(huì)返回10條數(shù)據(jù)給客戶端,然后客戶端在進(jìn)行排序返回給用戶。這個(gè)過(guò)程中返回的數(shù)據(jù)量(最大是10*N)會(huì)遠(yuǎn)大于用戶請(qǐng)求需要的數(shù)據(jù)量。

排名問(wèn)題。計(jì)算分值使用的詞頻和文檔頻率等信息都是基于自己分片的數(shù)據(jù)進(jìn)行的,不同分片中這些數(shù)據(jù)不同,直接導(dǎo)致各個(gè)分片算出來(lái)的分?jǐn)?shù)不具有統(tǒng)一參考性,影響排名準(zhǔn)確性。正確的做法是基于整體的詞頻、逆向文檔頻率等信息來(lái)算分?jǐn)?shù)。

3.查詢方式

ElasticSearch查詢的時(shí)候可以指定搜索類型: QUERY_AND_FEATCH、QUERY_THEN_FETCH(默認(rèn)的搜索方式)、DFS_QUERY_THEN_FEATCH、DFS_QUERY_AND_FEATCH。

1)QUERY_AND_FEATCH**

向索引的所有分片(shard)都發(fā)出查詢請(qǐng)求,各分片返回的時(shí)候把元素文檔(document)和計(jì)算后的排名信息一起返回。

這種搜索方式是最快的,只需要去shard查詢一次,但是各個(gè)shard返回的結(jié)果的數(shù)量之和可能是用戶要求的size的n倍。

2)QUERY_THEN_FETCH

先向所有的shard發(fā)出請(qǐng)求,各分片只返回排序和排名相關(guān)的信息(注意,不包括文檔document),然后按照各分片返回的分?jǐn)?shù)進(jìn)行重新排序和排名,取前size個(gè)文檔;接著去相關(guān)的shard取document。

這種方式返回的document與用戶要求的size是相等的。

3)DFS_QUERY_AND_FEATCH

在進(jìn)行真正的查詢之前,先把各個(gè)分片的詞頻和文檔頻率收集一下,然后進(jìn)行詞搜索的時(shí)候,各分片依據(jù)全局的詞頻率和文檔頻率進(jìn)行搜索和排名。

接著按照QUERY_AND_FEATCH的方式查詢。

4)DFS_QUERY_THEN_FEATCH

和上面一種方式一樣,也是先收集詞頻和文檔頻率,然后再按照QUERY_THEN_FEATC的方式查詢。

這種查詢要前后交互三次,速度最慢,但是排名最準(zhǔn)確。

二、相關(guān)度搜索問(wèn)題

1.問(wèn)題:ES是如何將相關(guān)度高的內(nèi)容能放在前面的?

在原理篇我們知道,當(dāng)將一個(gè)文檔保存到ElasticSearch會(huì)根據(jù)分詞的結(jié)果創(chuàng)建倒排索引,這種結(jié)構(gòu)是零散的,即每一個(gè)Term都會(huì)對(duì)應(yīng)Posting List。查詢的時(shí)候也是先經(jīng)過(guò)分詞,然后根據(jù)倒排索引查詢。

這里就有一個(gè)問(wèn)題,ElasticSearch是如何將匹配度最高的內(nèi)容放在前面的?如下圖所示,匹配效果最好的內(nèi)容放到了返回結(jié)果的最前面。

2.相關(guān)度

Lucene 使用布爾模型(Boolean model)查找匹配文檔,并使用權(quán)重來(lái)實(shí)現(xiàn)相關(guān)度搜索。

1)布爾模型

就是在查詢中使用?AND、OR、NOT(即與或非)來(lái)匹配文檔。

2)權(quán)重

權(quán)重由三個(gè)因素決定:詞頻、逆向文檔頻率、字段長(zhǎng)度歸一值

詞頻

指的是詞在文檔中出現(xiàn)的頻度是多少,頻度越高,權(quán)重越高。

詞頻=該詞在文檔中出現(xiàn)次數(shù)的平方根。

逆向文檔頻率

指的是詞在集合所有文檔里出現(xiàn)的頻率是多少,頻次越高,權(quán)重越低。

逆向文檔頻率=索引中文檔數(shù)量除以所有包含該詞的文檔數(shù),然后求其對(duì)數(shù)。

字段長(zhǎng)度歸一值

指的是字段的長(zhǎng)度是多少,字段越短,字段的權(quán)重越高 。

字段長(zhǎng)度歸一值 = 字段中詞數(shù)平方根的倒數(shù)。

3)向量空間模型

通常我們都是搜索多個(gè)字段,這樣就需要合并多詞權(quán)重,這個(gè)由向量空間模型實(shí)現(xiàn)。

具體合并過(guò)程基本都是數(shù)學(xué)上的算法,沒有詳細(xì)研究,有興趣的小伙伴可以到網(wǎng)上找一下。

3.相關(guān)度搜索

ES其實(shí)就是基于相關(guān)度的算法來(lái)計(jì)算分?jǐn)?shù),將分?jǐn)?shù)大的放在前面。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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