從一個線上問題看 Elasticsearch 數(shù)據(jù)清洗方式
如下問題來自真實(shí)場景,用對話方式模擬還原問題解答過程。
小明同學(xué)提問:銘毅老濕,如下兩個鏈接,我們底層的數(shù)據(jù)是帶空格的,但是用戶輸入可能不帶空格這種改怎么處理?

http://192.168.1.1/sr/6mm/
http://192.168.1.1/sr/6%20mm/銘毅老濕:上面兩個鏈接是用戶的行為?我們不能限制用戶的輸入是吧?

小明同學(xué):是哦,讓用戶輸入字符加空格或者不加空格去適配寫入的數(shù)據(jù),這樣會顯得系統(tǒng)很不“智能”,用戶體驗(yàn)會很差。
銘毅老濕:你能關(guān)注用戶體驗(yàn),不錯!這是程序員必備的思維方式。
小明同學(xué):那怎么解決類似問題呢?
銘毅老濕:其實(shí)最簡單、最常用的解決方式就是:寫入前做好數(shù)據(jù)清洗,去掉“特殊字符”、“空格”等。

圖片來自互聯(lián)網(wǎng)
小明同學(xué):這個我知道,不就是ETL嘛!包含數(shù)據(jù)的抽取、轉(zhuǎn)換和加載。ETL著重體現(xiàn)在一些數(shù)據(jù)清洗轉(zhuǎn)化功能,比如空值處理、規(guī)范化數(shù)據(jù)、數(shù)據(jù)替換、數(shù)據(jù)驗(yàn)證等等。。。
咦,我的問題不就是“空值處理”嘛~~
銘毅老濕:那你說說怎么弄?
小明同學(xué):“一臉的疑惑似乎舒緩了一些”,寫入前去掉空格。java 里面貌似一行正則代碼就能搞定。
?str?=?str.replaceAll("\\s+",?"");
我明白啦!
銘毅老濕:小明同學(xué)別著急!那用戶檢索怎么搞?
小明同學(xué):原理一樣的,前端接收用戶請求,做一下清洗處理就可以。我走啦,銘毅老濕。
銘毅老濕:等等~~~你的源頭數(shù)據(jù)從哪里來?
小明同學(xué):MySQL呀。
銘毅老濕:那你是怎么同步數(shù)據(jù)的?
小明同學(xué):借助 logstash,logstash-input-jdbc 同步插件非常好用,支持各種類型的關(guān)系型數(shù)據(jù)庫的同步。我還畫了各種類型同步到 Elasticsearch 的各種實(shí)現(xiàn)呢?手機(jī)上有,你看一下。

不同源數(shù)據(jù)同步到 Elasticsearch 實(shí)現(xiàn)方案
銘毅老濕:不錯,總結(jié)的很全面
。那我問你,你這一行 java 代碼往哪里寫?
小明同學(xué):我插
,這點(diǎn)我忘記了。我想一下,logstash 是用 ruby 語言寫的,找一下 ruby 語言如何處理空格就可以了。
小明同學(xué)拿起手機(jī)查了2分鐘,找到啦!
mutate?{
????gsub?=>?[
??????"Animal",?"\s",?""
????]
}語言不同,和 java 語法都有相通的地方。
我走啦,還是你考慮的周全,銘毅老濕!
銘毅老濕:別著急,那如果不用 logstash 處理,該如何搞定呢?假定你的 logstash 不允許再改了。
小明同學(xué):這個假如不存在的,想改就改,非常受控。嘻嘻~~~,讓我想想。。。。。。
與 logstash filter 中轉(zhuǎn)處理環(huán)節(jié)有個同等重量級的 ingest 預(yù)處理借助腳本可以實(shí)現(xiàn),還有個我不大確認(rèn),自定義分詞能否實(shí)現(xiàn)呢?
銘毅老濕:你說的很對,自定義分詞包含哪三個環(huán)節(jié)?如何實(shí)現(xiàn)咋實(shí)現(xiàn)有思路嗎?
小明同學(xué):這個我有點(diǎn)忘記了,得查一下文檔。有了,這個圖很萬能。

涉及細(xì)節(jié)不少,我得回去研究一下了。
多謝銘毅老濕~~我真的得走啦,再見!

間隔了一天。。。。。。
第二天,小明帶來了他的實(shí)現(xiàn)。
銘毅老濕:小明,你講一下實(shí)現(xiàn)思路吧?小明同學(xué):我用了兩種方法,
方法一:在自定義分詞的 character filter 環(huán)節(jié)借助 pattern replace 方式將空格轉(zhuǎn)化為沒有任何字符,就相當(dāng)于去掉了空格。 方法二:通過 character filter 環(huán)節(jié)的 Mapping 將空格字符等同于無字符處理,就間接去掉了空格。 這兩種方法本質(zhì)都是借助之前給的圖的第一個環(huán)節(jié):character filter 字符過濾的方式實(shí)現(xiàn)的。
這里有可供演示的 DSL,我給你演示一下:
PUT?my-index-000001
{
??"settings":?{
????"analysis":?{
??????"filter":?{
????????"whitespace_remove":?{
??????????"type":?"pattern_replace",
??????????"pattern":?"?",
??????????"replacement":?""
????????}
??????},
??????"analyzer":?{
????????"auto_analyzer":?{
??????????"filter":?[
????????????"lowercase",
????????????"whitespace_remove"
??????????],
??????????"type":?"custom",
??????????"tokenizer":?"keyword"
????????}
??????}
????}
??},
??"mappings":?{
????"properties":?{
??????"title":?{
????????"type":?"text",
????????"analyzer":?"auto_analyzer",
????????"fields":?{
??????????"field":?{
????????????"type":?"keyword"
??????????}
????????}
??????}
????}
??}
}
POST?my-index-000001/_bulk
{"index":{"_id":1}}
{"title":"6mm"}
{"index":{"_id":2}}
{"title":"6?mm"}
{"index":{"_id":3}}
{"title":"6????mm"}
GET?my-index-000001/_analyze
{
??"text":?["6mm",?"6?mm",?"6???mm"],
??"analyzer":?"auto_analyzer"
}
##?三類數(shù)據(jù)都能召回
POST?my-index-000001/_search
{
??"query":?{
????"match":?{
??????"title":?"6mm"
????}
??}
}https://www.elastic.co/guide/en/elasticsearch/reference/7.17/analysis-pattern_replace-tokenfilter.html
PUT?my-index-000002
{
??"settings":?{
????"analysis":?{
??????"analyzer":?{
????????"my_analyzer":?{
??????????"tokenizer":?"standard",
??????????"char_filter":?[
????????????"my_char_filter"
??????????]
????????}
??????},
??????"char_filter":?{
????????"my_char_filter":?{
??????????"type":?"mapping",
??????????"mappings":?[
????????????"""\u0020=>"""
??????????]
????????}
??????}
????}
??},
??"mappings":?{
????"properties":?{
??????"title":?{
????????"type":?"text",
????????"analyzer":?"my_analyzer",
????????"fields":?{
??????????"field":?{
????????????"type":?"keyword"
??????????}
????????}
??????}
????}
??}
}
POST?my-index-000002/_bulk
{"index":{"_id":1}}
{"title":"6mm"}
{"index":{"_id":2}}
{"title":"6?mm"}
{"index":{"_id":3}}
{"title":"6????mm"}
GET?my-index-000002/_analyze
{
??"text":?["6mm",?"6?mm",?"6???mm"],
??"analyzer":?"my_analyzer"
}
##?三類數(shù)據(jù)都能召回
POST?my-index-000002/_search
{"query":{"match":{"title":"6mm"}}}銘毅老濕:不錯,不錯,考慮的很全面。那小明同學(xué),你能否總結(jié)一下:Elasticsearch 數(shù)據(jù)預(yù)處理的方式有哪些?
小明同學(xué):我給你現(xiàn)場畫個腦圖吧。

銘毅老濕:哎呦,不錯哦。。。
未完,待續(xù)~~~
推薦
和 20000+ Elastic小伙伴一起學(xué)習(xí) ElasticStack!

