?

基于ElasticSearch分布式搜索引擎的信息檢索方法研究

2023-12-28 08:35董元和李恩澤薛賢紅
關鍵詞:詞條字段分詞

董元和,賈 炎,朱 勇,李恩澤,薛賢紅

(1.湖北師范大學 計算機與信息工程學院,湖北 黃石 435002;2.黃石市第十四中學,湖北 黃石 435002)

0 引言

隨著互聯網的快速發展,每天產生大量數據,但其中有很多是臟數據。傳統的搜索方式無法應對海量信息的并發查詢和篩選,也無法滿足多關鍵詞組合的短文本搜索需求,搜索結果的相關性也有一定偏差。因此,本文提出使用基于ElasticSearch分布式搜索引擎[1]的方法,提供更具體、有效和深入的垂直搜索服務[2],研究重點是基于分布式搜索引擎,結合中文分詞技術和搜索相關性算分排序技術,設計并實現基于ElasticSearch分布式搜索引擎的信息檢索系統。

1 系統關鍵技術

1.1 分詞器

在本文所闡述的系統中,對用戶輸入的搜索內容進行分詞處理是一個重要步驟,本系統采用的是ik分詞器[3]。ElasticSearch內置了分詞器,如標準分詞器、簡單分詞器、空白詞器等。但這些分詞器對中文的支持并不友好,不能按中文的語言習慣進行分詞。而ik分詞器就是一個標準的中文分詞器,它可以根據定義的字典對域進行分詞,并且支持用戶配置自己的字典。除此之外,ik分詞器還具有2種分詞算法:ik_smart(最粗粒度的拆分)和ik_max_word(最細粒度的拆分),ik_max_word比ik_smart劃分的詞條要更多。

1.2 倒排索引

倒排索引[4]的概念是基于關系型數據庫的正向索引而言的。正向索引需要逐行掃描也就是全表掃描,隨著數據量增加,其查詢效率也會越來越低。當數據量達到數百萬時,就是一場災難。因此,針對這類用正向索引會導致一些性能問題的業務可以考慮采取倒排索引的方式。創建倒排索引是對正向索引的一種特殊處理,步驟如下:

1) 將每一個文檔(用來搜索的數據,其中的每一條數據就是一個文檔)。的數據利用算法分詞(通常會借助分詞器),得到一個個詞條(對文檔數據或用戶搜索數據,利用下文提到的分詞器進行分詞,得到的具備含義的詞語就是詞條);

2) 創建表,每行數據包括詞條、詞條所在文檔id、位置等信息;

3) 因為詞條的唯一性,可以給詞條創建索引(就是文檔的集合,類似數據庫的表),例如hash表結構索引。

其整體流程如圖1,以搜索“如家酒店”為例,用戶輸入條件“如家酒店”進行搜索;對用戶輸入內容分詞,得到詞條:“如家”“酒店”;拿著詞條在倒排索引表2中查找,可以得到包含詞條的文檔id:1、2、3;拿著文檔id到正向索引表1中查找具體的記錄。

表1 正向索引idname1如家民宿2假日酒店3如家酒店4皇冠假日5清沐表2 倒排索引詞條文檔id如家1,3酒店2,3清沐5皇冠4假日2,4

圖1 倒排索引流程圖

雖然要先查詢倒排索引,再查詢正向索引,但是無論是詞條、還是文檔id都建立了索引,查詢速度非???無須全表掃描。另外,ElasticSearch不僅提供了內置的分詞器,也可以進行自定義分詞器,并通過不同分詞器的組合以及相關屬性設置,去創建符合研究數據的分詞器,極大地優化建立索引的速度。

1.3 相關性算分

相關性描述的是一個文檔和查詢語句匹配的程度。ElasticSearch會對每個匹配查詢條件的結果進行算分(_score),_score的評分越高,相關度就越高。在ElasticSearch中,早期使用的打分算法是TF-IDF[5]算法,公式如下:

(1)

由此,可以得到結論:詞條出現頻率越高,相關性也越高。在后來的5.1版本升級中,ElasticSearch將算法改進為BM25[6]算法,公式如下:

(2)

這里tftq表示單詞t在query中的詞頻,Lave是所有文檔的平均長度,Ld是文檔d的長度,k3是一個可調正參數,來矯正query中的詞頻范圍。經過試驗,上面三個可調參數,k1和k3可取1.2與2之間的數,b取0.75.顯然,詞條頻率仍然對相關性占主導作用,但受到其他參數制約,使得結果更加準確。

2 具體實現

2.1 系統架構

本系統以Elasticsearch作為全文搜索引擎,客戶端訪問后端搜索模塊時可以直接調用搜索服務,也可以通過調用ElasticSearch搜素引擎間接調用搜索服務,并將數據同步到數據庫中。系統架構圖如圖2所示。

圖2 系統架構圖

2.2 環境搭建

首先需要安裝ElasticSearch并且部署單點ElasticSearch服務;其次本系統還需要部署Kibana容器,因此需要讓ElasticSearch和Kibana容器互聯,所以先利用docker容器創建一個es-net網絡;然后采用ElasticSearch的7.12.1版本的鏡像,運行docker加載命令導入數據。同理還有Kibana的tar包也需要這樣做。最后運行docker run命令,部署單點ElasticSearch和Kibana.接下來需要離線安裝ik插件,安裝插件需要知道ElasticSearch的plugins目錄位置,因為系統用了數據卷掛載,所以需要查看ElasticSearch的數據卷目錄,根據Mountpoint字段的屬性值即可知道plugins目錄被掛載到了哪個目錄,接著將插件拷貝到該目錄中,之后重新啟動ElasticSearch服務即可。

2.3 創建索引庫

倒排索引結構雖然不復雜,但是一旦數據結構改變(比如改變了分詞器),就需要重新創建倒排索引,因此索引庫一旦創建,無法修改mapping,這就需要根據關系表字段重新定義自己的索引庫。同時,創建索引庫最關鍵的是mapping映射,而mapping映射要考慮的信息包括type(字段數據類型)、index(是否創建索引,默認為true)、analyzer(使用哪種分詞器)、properties(該字段的子字段),針對此種情況可以考慮利用代碼創建索引庫,方便后期修改屬性時刪除索引庫并重新創建索引庫,核心代碼如下:

void testCreateIndex() throws IOException {

// 1.準備Request

CreateIndexRequest request = new CreateIndexRequest("hotel");

// 2.準備請求參數MAPPING_TEMPLATE是自定義的索引庫結構

request.source(MAPPING_TEMPLATE, XContentType.JSON);

// 3.發送請求

client.indices().create(request, RequestOptions.DEFAULT);

}

2.4 基礎搜索功能實現

此小節主要是完成信息的基本查詢,包括全文檢索查詢,精確查詢,搜索查詢等。全文檢索查詢首先要對用戶搜索的內容做分詞,得到詞條;根據詞條去倒排索引庫中匹配,得到文檔id;根據文檔id找到記錄,返回給用戶,核心代碼如下:

void testMatch() throws IOException {

// 1.準備request

SearchRequest request = new SearchRequest("hotel");

// 2.準備請求參數

request.source().query(QueryBuilders.multiMatchQuery("外灘如家", "name", "brand", "city"));

// 3.發送請求,得到響應

SearchResponse response = client.search(request, RequestOptions.DEFAULT);

// 4.結果解析

handleResponse(response);

}

上述代碼中,multiMatchQuery是實現多字段查詢,即任意一個字段符合條件就算符合查詢條件,這種查詢方式在正向索引庫中實現起來要麻煩很多,性能也不夠好。在ElasticSearch中還可以借助組合字段將多字段的值利用copy_to合并,提供給用戶搜索,這樣比上面代碼中多個字段分開查詢效率還要更高。而對于精確查詢就簡單了很多,與上面的查詢相比,差異僅僅在查詢條件,需要查詢參數值與索引庫值完全匹配,就跟關系型數據庫的字段查詢相似,只是數據足夠大時,ElasticSearch查詢效率要更高,代碼如下:

void testBool() throws IOException {

……

request.source().query(

QueryBuilders.boolQuery()

.must(QueryBuilders.termQuery("city", "杭州"))

.filter(QueryBuilders.rangeQuery("price").lte(250))

);

……

}

2.5 地理搜索功能實現

ElasticSearchES中支持兩種地理坐標數據類型,geo_point(由緯度(latitude)和經度(longitude)確定的一個點)和geo_shape(有多個geo_point組成的復雜幾何圖形)。首先基于這個location坐標,然后按照距離對信息排序,核心代碼如下:

String location = params.getLocation();

if (StringUtils.isNotBlank(location)) {

request.source().sort(SortBuilders

.geoDistanceSort("location", new GeoPoint(location))

.order(SortOrder.ASC)

.unit(DistanceUnit.KILOMETERS)

);

}

2.6 算分排序功能實現

對于商業性質很強的業務場景,搜索結果優先順序是十分重要的,關系到運營發展的重要決策和盈利能力。那么就需要借助算分算法得出相對比較公平的分數并進行排序并展現給用戶,ElastiSearch利用match查詢時,文檔結果會根據與搜索詞條的關聯度打分(_score),返回結果時按照分值降序排列。

但是在B2B,B2C,C2C這種商業模式下,除了流量定向分發,還需要人為地控制相關性分數,提高搜索優先級,優先展示在用戶列表中,這需要借助ElastiSearch的算分函數function_score查詢,它可以影響算分,算分高了,自然排名也就高了。而function_score包含3個要素:過濾條件(哪些文檔要加分)、算分函數(如何計算function_score)、加權方式(function_score與query_score如何運算)。想讓指定的信息排名靠前,那么可以給這些信息添加一個標記,這樣在過濾條件中就可以根據這個標記來判斷,是否要提高算分。比如,給查詢信息添加一個Boolean類型字段isAD,這樣function_score包含3個要素就很好確定了:過濾條件:判斷isAD是否為true,如果是就添加分數權值;算分函數:可以用最簡單暴力的weight來實現固定加權值;加權方式:可以用默認的相乘提高算分,代碼如下:

FunctionScoreQueryBuilderfunctionScoreQuery=QueryBuilders.functionScoreQuer(

boolQuery,

new FunctionScoreQueryBuilder.FilterFunctionBuilder[]{

new FunctionScoreQueryBuilder.FilterFunctionBuilder(

QueryBuilders.termQuery("isAD", true),

ScoreFunctionBuilders.weightFactorFunction(10)

)

}

);

如圖3,在查詢之前設置標記字段isAD為true,這樣會增加該條數據的權重,分數會被提高,這樣查詢結果中排序靠前的記錄id值跟事先設置的文檔id相同,這個結果也說明ElastiSearch是可以很方便地實現競爭排名。

圖3 排名實現結果

3 結語

基于ElasticSearch分布式搜索引擎的信息檢索系統,不僅可以實現對信息進行全文檢索查詢、精確查詢、地理坐標查詢以及算分排序等重要功能,而且搜索性能也會有大幅度提升,部署也簡單方便,但仍有不足之處需要完善更新,比如未實現數據聚合實時搜索效果;未實現自動補全用戶在搜索框輸入字符時提示出與該字符有關的搜索項等功能。對此,后續可以考慮對用戶常用搜索詞條進行緩存處理。

猜你喜歡
詞條字段分詞
圖書館中文圖書編目外包數據質量控制分析
分詞在英語教學中的妙用
結巴分詞在詞云中的應用
結巴分詞在詞云中的應用
2016年4月中國直銷網絡熱門詞條榜
2016年3月中國直銷網絡熱門詞條榜
2016年9月中國直銷網絡熱門詞條榜
大數據相關詞條
CNMARC304字段和314字段責任附注方式解析
無正題名文獻著錄方法評述
91香蕉高清国产线观看免费-97夜夜澡人人爽人人喊a-99久久久无码国产精品9-国产亚洲日韩欧美综合