ElasticSearch搜索提示實(shí)現(xiàn)

一簿训、四種Suggester介紹

Suggesters基本的運(yùn)作原理是將輸入的文本分解為token闰渔,然后在索引的字典里查找相似的term并返回晰房。 根據(jù)使用場景的不同滨嘱,Elasticsearch里設(shè)計(jì)了4種類別的Suggester,分別是:

?Term Suggester
?Completion Suggester
?Phrase Suggester
?Context Suggester

二灿椅、四個(gè)Suggester比較[1]

Term Suggester——基于編輯距離算法實(shí)現(xiàn)套蒂。在提供建議之前,對輸入的文本進(jìn)行分析

Phrase suggester——在 term suggester之上添加額外的邏輯以選擇整個(gè)經(jīng)校正的短語茫蛹,而不是基于 ngram-language 模型加權(quán)的單個(gè) token

Completion Suggester——只能用于前綴查詢操刀,速度很快,性能要求高

?需求場景是:輸入一個(gè)字符麻惶,即時(shí)發(fā)送一個(gè)請求查詢匹配項(xiàng)?數(shù)據(jù)結(jié)構(gòu):并非是倒排索引實(shí)現(xiàn)的馍刮,而是將分詞的數(shù)據(jù)編碼成FST和索引一起存放;FST會(huì)被加載進(jìn)內(nèi)存窃蹋,速度很快?限制:需要對查詢字段指定為Completion

Context Suggester——可以通過篩選提供建議,context 支持兩種類型静稻,分別是category(任意字符串)警没,geo(地理位置信息)

準(zhǔn)確度completion > phrase > term

三、Completion Suggester Mapping的設(shè)置

因?yàn)?code>Completion Suggester的搜索補(bǔ)全和搜索提示是要求查詢的字段typeCompletion類型的振湾。所以在定義Mapping時(shí)候需要將被查詢的字段type定義為completion類型杀迹。查詢的Mapping如下:

PUT document {
    "mappings": {
        "properties": {
            "id": {
                "type": "keyword"
            },
            "doc_name": {
                "type": "completion",
                "analyzer": "ik_max_word"
            },
            "doc_number": {
                "type": "text",
                "analyzer": "ik_max_word"
            },
            "doc_type": {
                "type": "text",
                "analyzer": "ik_max_word"
            },
            "keywords": {
                "type": "completion",
                "analyzer": "ik_max_word"
            },
            "pubdate": {
                "type": "date",
                "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
            },
            "attachment": {
                "properties": {
                    "content": {
                        "type": "text",
                        "analyzer": "ik_max_word"
                    }
                }
            }
        }
    }
}

因?yàn)樾枰M(jìn)行全文檢索添加了attachment的內(nèi)容

四、TransportClientREST client的區(qū)別[2]

Elasticsearch計(jì)劃在Elasticsearch 7.0中棄用TransportClient押搪,
在8.0中完全刪除它树酪。相反,您應(yīng)該使用Java高級REST client大州,rest client執(zhí)行HTTP請求來執(zhí)行操作续语,無需再序列化的Java請求。

TransportClient 是ElasticSearch(java)客戶端封裝對象厦画,使用transport模塊遠(yuǎn)程連接到Elasticsearch集群疮茄,該transport node并不會(huì)加入集群滥朱,而是簡單的向ElasticSearch集群上的節(jié)點(diǎn)發(fā)送請求。transport node使用輪詢機(jī)制進(jìn)行集群內(nèi)的節(jié)點(diǎn)進(jìn)行負(fù)載均衡力试,盡管大多數(shù)操作(請求)可能是“兩跳操作”徙邻。(圖片來源于Elasticsearch權(quán)威指南)

Java REST客戶端有兩種風(fēng)格:

?Java Low Level REST Clientelasticsearch client低級別客戶端。它允許通過http請求與Elasticsearch集群進(jìn)行通信畸裳。API本身不負(fù)責(zé)數(shù)據(jù)的編碼解碼缰犁,由用戶去編碼解碼。它與所有的ElasticSearch版本兼容怖糊。
?Java High Level REST ClientElasticsearch client官方高級客戶端民鼓。基于低級客戶端蓬抄,它定義的API,已經(jīng)對請求與響應(yīng)數(shù)據(jù)包進(jìn)行編碼解碼丰嘉。

五、基于ElasticSearch Java REST Client API的自動(dòng)補(bǔ)全

 /**
    * @param suggestField 查詢搜索補(bǔ)全的字段
    * @param suggestValue 查詢搜索補(bǔ)全的值
    * @return 返回搜索補(bǔ)全list
    * @throws IOException IO異常
  */
  public List<String> suggestSearchList(String suggestField, String suggestValue) throws IOException {

        /**
         * ElasticSearch 7.X版本以上 不在使用TransportClient進(jìn)行客戶端連接 所以使用client進(jìn)行連接客戶端無法進(jìn)行使用
         * 7.X版本將搜索補(bǔ)全(completion)合并到SuggestBuilders中進(jìn)行使用嚷缭,在SuggestBuilders中構(gòu)建completionSuggestion搜索參數(shù)
         */

        // 構(gòu)建SearchRequest饮亏、SearchSourceBuilder 指定查詢的庫
        // SearchRequest searchRequest = new SearchRequest(ESConst.ES_INDEX);
        SearchRequest searchRequest = new SearchRequest("testdata");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        // 控制顯示內(nèi)容 (優(yōu)化查詢效率將所有無關(guān)查詢提示字段都不顯示)
        String[] excludeFields = new String[] {"doc_number","doc_type","attachment","doc_keywords","id","pubdate","doc_name"};
        String[] includeFields = new String[] {""};
        searchSourceBuilder.fetchSource(includeFields, excludeFields);

        // 構(gòu)建completionSuggestionBuilder傳入查詢的參數(shù)
        CompletionSuggestionBuilder completionSuggestionBuilder = SuggestBuilders.completionSuggestion(suggestField).prefix(suggestValue).size(10);
        SuggestBuilder suggestBuilder = new SuggestBuilder();
        // 定義查詢的suggest名稱
        suggestBuilder.addSuggestion(suggestField+"_suggest", completionSuggestionBuilder);
        searchSourceBuilder.suggest(suggestBuilder);
        searchRequest.source(searchSourceBuilder);

        // 執(zhí)行查詢
        SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        // 獲取查詢的結(jié)果
        Suggest suggest = searchResponse.getSuggest();

        Set<String> suggestSet = new HashSet<>();
        int maxSuggest = 0;
        if (suggest != null) {
            // 獲取Suggestion的結(jié)果
            Suggest.Suggestion result = suggest.getSuggestion(suggestField+"_suggest");
            // 遍歷獲得查詢結(jié)果的Text
            for (Object term : result.getEntries()) {
                if (term instanceof CompletionSuggestion.Entry) {
                    CompletionSuggestion.Entry item = (CompletionSuggestion.Entry) term;
                    if (!item.getOptions().isEmpty()) {
                        // 若item的option不為空,循環(huán)遍歷
                        for (CompletionSuggestion.Entry.Option option : item.getOptions()) {
                            String tip = option.getText().toString();
                            if (!suggestSet.contains(tip)) {
                                suggestSet.add(tip);
                                ++maxSuggest;
                            }
                        }
                    }
                }
                if (maxSuggest >= 10) {
                    break;
                }
            }
        }

        return Arrays.asList(suggestSet.toArray(new String[]{}));
    }

代碼思路:

1、首先實(shí)例化構(gòu)建SearchRequestSearchSourceBuilder阅爽,查詢document文檔路幸;

2、控制查詢顯示的內(nèi)容付翁,使用searchSourceBuilder.fetchSource控制excludeFieldsincludeFields(無關(guān)的要素不進(jìn)行查詢)简肴;

3、構(gòu)建completionSuggestionBuilder百侧,以參數(shù)形式傳入suggestFieldsuggestValue砰识,默認(rèn)設(shè)置size為10;

4佣渴、定義查詢的suggest_name辫狼,通過suggestBuilder.addSuggestion進(jìn)行添加;

5辛润、執(zhí)行查詢膨处,searchResponse.getSuggest獲得查詢的結(jié)果;

6砂竖、遍歷獲得Suggest中的text真椿,輸出傳入list返回給前端。

六乎澄、實(shí)現(xiàn)效果截圖

提示1
提示2
提示3

var code = "22f45cca-2cf5-490b-bffa-c99574616258"

References

[1] 四個(gè)Suggester比較: http://www.reibang.com/p/34db35d13cd3
[2] TransportClientREST client的區(qū)別: https://blog.csdn.net/prestigeding/article/details/83188043

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末突硝,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子三圆,更是在濱河造成了極大的恐慌狞换,老刑警劉巖避咆,帶你破解...
    沈念sama閱讀 222,681評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異修噪,居然都是意外死亡查库,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,205評論 3 399
  • 文/潘曉璐 我一進(jìn)店門黄琼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來樊销,“玉大人,你說我怎么就攤上這事脏款∥唬” “怎么了?”我有些...
    開封第一講書人閱讀 169,421評論 0 362
  • 文/不壞的土叔 我叫張陵撤师,是天一觀的道長剂府。 經(jīng)常有香客問我,道長剃盾,這世上最難降的妖魔是什么腺占? 我笑而不...
    開封第一講書人閱讀 60,114評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮痒谴,結(jié)果婚禮上衰伯,老公的妹妹穿的比我還像新娘。我一直安慰自己积蔚,他們只是感情好意鲸,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,116評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著尽爆,像睡著了一般怎顾。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上教翩,一...
    開封第一講書人閱讀 52,713評論 1 312
  • 那天杆勇,我揣著相機(jī)與錄音,去河邊找鬼饱亿。 笑死,一個(gè)胖子當(dāng)著我的面吹牛闰靴,可吹牛的內(nèi)容都是我干的彪笼。 我是一名探鬼主播,決...
    沈念sama閱讀 41,170評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼蚂且,長吁一口氣:“原來是場噩夢啊……” “哼配猫!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起杏死,我...
    開封第一講書人閱讀 40,116評論 0 277
  • 序言:老撾萬榮一對情侶失蹤泵肄,失蹤者是張志新(化名)和其女友劉穎捆交,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體腐巢,經(jīng)...
    沈念sama閱讀 46,651評論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡品追,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,714評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了冯丙。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片肉瓦。...
    茶點(diǎn)故事閱讀 40,865評論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖胃惜,靈堂內(nèi)的尸體忽然破棺而出泞莉,到底是詐尸還是另有隱情,我是刑警寧澤船殉,帶...
    沈念sama閱讀 36,527評論 5 351
  • 正文 年R本政府宣布鲫趁,位于F島的核電站,受9級特大地震影響利虫,放射性物質(zhì)發(fā)生泄漏挨厚。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,211評論 3 336
  • 文/蒙蒙 一列吼、第九天 我趴在偏房一處隱蔽的房頂上張望幽崩。 院中可真熱鬧,春花似錦寞钥、人聲如沸慌申。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,699評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蹄溉。三九已至,卻和暖如春您炉,著一層夾襖步出監(jiān)牢的瞬間柒爵,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,814評論 1 274
  • 我被黑心中介騙來泰國打工赚爵, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留棉胀,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,299評論 3 379
  • 正文 我出身青樓冀膝,卻偏偏與公主長得像唁奢,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子窝剖,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,870評論 2 361

推薦閱讀更多精彩內(nèi)容