1、詞頻相關(guān)實(shí)戰(zhàn)問題最近詞頻統(tǒng)計(jì)問題被問到的非常多,詞頻統(tǒng)計(jì)問題清單如下:
如上三個(gè)問題都可以歸結(jié)為:Elasticsearch 文檔詞頻統(tǒng)計(jì)問題。該問題在檢索、統(tǒng)計(jì)領(lǐng)域應(yīng)用的非常多。 那么 Elasticsearch 如何實(shí)現(xiàn)詞頻統(tǒng)計(jì)呢?有必要梳理一下。 2、詞頻統(tǒng)計(jì)探討之前的文章《Elasticsearch詞頻統(tǒng)計(jì)實(shí)現(xiàn)與原理解讀》,解決的是:Q3 提及的某索引中特定關(guān)鍵詞統(tǒng)計(jì)的問題。 解決方案是:text 字段開啟 fielddata,咱們在《長津湖影評可視化》中詞云的可視化本質(zhì)也是這種方案。 那么,對于給定文檔的詞頻統(tǒng)計(jì)呢? 原來開啟 fielddata 的方案就可以實(shí)現(xiàn),舉例如下: DELETE message_index 無非在聚合的時(shí)候,加上query 語句指定了特定 id 進(jìn)行檢索。 這種方法的缺點(diǎn)在于:正如 Q3 所說,聚合效率低。 看過上次直播的同學(xué),可能會閃現(xiàn)一種想法,寫入前打 tag 的方式能解決嗎? 可以解決,但有個(gè)前提。先畫個(gè)圖解釋一下: 這個(gè)打 tag 的字段非全量,而是特定的指定腳本處理的部分。下一小節(jié)詳細(xì)實(shí)現(xiàn)一把。 其實(shí),除了開啟 fielddata 和 打 tag 之外,在 Elasticsearch 中有 termvectors 接口也能實(shí)現(xiàn)文檔詞頻統(tǒng)計(jì)。下一小節(jié)一并實(shí)現(xiàn)。 3、詞頻統(tǒng)計(jì)實(shí)現(xiàn)3.1 text 開啟 fielddata 后聚合方案第 2 部分已有實(shí)現(xiàn)說明,不再贅述。 3.2 寫入前打 tag,寫入后聚合統(tǒng)計(jì)方案還是用第 2 部分的數(shù)據(jù),說明如下: PUT _ingest/pipeline/add_tags_pipeline 實(shí)現(xiàn)后,結(jié)果如下: 這種統(tǒng)計(jì)的依然是:關(guān)鍵詞(key)和文檔(doc_count)的統(tǒng)計(jì)關(guān)系。 什么意思呢? "key":“沉溺”,“doc_count”:3 本質(zhì)含義是:“沉溺”在三個(gè)不同的文檔中出現(xiàn)了。 細(xì)心的讀者會發(fā)現(xiàn),文檔 1 中“沉溺”出現(xiàn)了2次,這種打 tag 統(tǒng)計(jì)是不準(zhǔn)確的。 3.3 term vectors 統(tǒng)計(jì)PUT message_index 解釋一下:
with_positions_offsets_payloads 是Lucene 的參數(shù)之一,釋義如下: 可以理解為:存儲分詞單元(term vector)、位置(Token position)、偏移值(offset)、有效負(fù)載(payload,猜測是ES 新增的)。 默認(rèn)會統(tǒng)計(jì)詞頻信息,默認(rèn)term information 為true。此外,還有 term statistics 和 field statistics 類型供設(shè)置和實(shí)現(xiàn)不同的統(tǒng)計(jì),詳細(xì)內(nèi)容參考官方文檔即可。 https://www./guide/en/elasticsearch/reference/current/docs-termvectors.html 執(zhí)行: GET message_index/_termvectors/1?fields=message 后的返回結(jié)果如下: 這種基于特定文檔的詞頻統(tǒng)計(jì)是傳統(tǒng)意義上我們理解的詞頻統(tǒng)計(jì)。 默認(rèn)情況下,term vectors是實(shí)時(shí)的,而不是接近實(shí)時(shí)的??梢酝ㄟ^將 realtime 參數(shù)設(shè)置為 false 來更改。實(shí)時(shí)就意味著可能會有性能問題。 3.4 先分詞,后 term vectors 統(tǒng)計(jì)在我擔(dān)心僅 termvectors 可能帶來的性能問題的時(shí)候,我想到了如下的解決方案。 前提:寫入之前除了存儲 message 字段,加了一個(gè)分詞結(jié)果組合字段,該字段每個(gè)詞用空格做分隔。 message 字段的前置分詞需要自己調(diào)用 analyzer API 實(shí)現(xiàn)。 有了切詞后的字段,再做統(tǒng)計(jì)會更快。 具體實(shí)現(xiàn)如下: DELETE message_ext_index 強(qiáng)調(diào)一下:message_ext 使用的 whitespace 分詞器。 4、小結(jié)關(guān)于詞頻統(tǒng)計(jì),本文給出四種方案。只有第3、4種方案結(jié)合termvectors 實(shí)現(xiàn)是嚴(yán)格意義上的詞頻統(tǒng)計(jì),其他兩種是詞頻-文檔關(guān)系的統(tǒng)計(jì)。 考慮到方式3的實(shí)時(shí)分詞可能的性能問題,擴(kuò)展想到方案4前置分詞的方式,能有效提高統(tǒng)計(jì)效率。本質(zhì)也是空間換時(shí)間。 你的實(shí)戰(zhàn)中如何實(shí)現(xiàn)的詞頻統(tǒng)計(jì)呢?歡迎留言說一下你的實(shí)現(xiàn)方式和思考。 參考https:///Network/Articles/Article?AID=7c417f9f-5bde-4519-9bd5-39957d184a07 https://discuss./t/word-count-frequency-per-field/159910 https://www./guide/en/elasticsearch/reference/current/docs-termvectors.html 推薦更短時(shí)間更快習(xí)得更多干貨! 已帶領(lǐng)70位球友通過 Elastic 官方認(rèn)證! 中國僅通過百余人 |
|