曹書林,呂青松,王一帆,尹乾,鄭新
(北京師范大學(xué)信息科學(xué)與技術(shù)學(xué)院,北京,100875)
基于Lucene與Socket通信的中文搜索引擎的設(shè)計(jì)與實(shí)現(xiàn)
曹書林,呂青松,王一帆,尹乾,鄭新
(北京師范大學(xué)信息科學(xué)與技術(shù)學(xué)院,北京,100875)
Lucene是一個(gè)用Java寫的全文檢索引擎工具包,面向?qū)ο蠖鄬臃庋b,提供了一個(gè)低耦合、與平臺(tái)無關(guān)的、可進(jìn)行二次開發(fā)的全文檢索引擎架構(gòu),是這幾年最受歡迎的信息檢索程序庫;基于流式 Socket的網(wǎng)絡(luò)編程是設(shè)計(jì)網(wǎng)絡(luò)通信程序的一種有效方法。本文基于Lucene,采用中文分詞技術(shù),設(shè)計(jì)并實(shí)現(xiàn)了中文搜索引擎,同時(shí)應(yīng)用Java和PHP的Socket網(wǎng)絡(luò)編程技術(shù),實(shí)現(xiàn)了外網(wǎng)通過PHP網(wǎng)頁使用Lucene服務(wù)的功能。
中文搜索引擎;Lucene;Socket;中文分詞;java;PHP
中文搜索引擎是指以網(wǎng)絡(luò)上的中文信息為主要對(duì)象,提供信息的自動(dòng)收集、過濾、索引和檢索導(dǎo)航等服務(wù)的搜索引擎[1]。本文在Lucene的基礎(chǔ)上,進(jìn)行二次開發(fā),設(shè)計(jì)了搜索引擎核心的三大模塊:索引模塊,檢索模塊和web交互模塊,使用了中文分詞技術(shù)和關(guān)鍵詞高亮顯示技術(shù),實(shí)現(xiàn)了按關(guān)鍵詞快速搜索的界面友好的中文搜索引擎。
搜索引擎有基本的五大模塊,分別是信息采集,信息處理,索引,查詢和web交互。本文研究的是如何在信息處理分析的基礎(chǔ)上,建立一個(gè)完整的中文搜索引擎。所以該系統(tǒng)主要由三部分組成:建立索引庫,建立查詢服務(wù)器,建立web交互。
Lucene將文本以倒排索引的數(shù)據(jù)結(jié)構(gòu)進(jìn)行存儲(chǔ),把文檔中提取出來的文字作為關(guān)鍵字[2],該倒排索引的基本結(jié)構(gòu)如下:
一個(gè)Document代表索引庫的一個(gè)文檔。要搜索的信息封裝成Document后通過IndexWriter寫入索引庫,這也是能返回給用戶作為搜索結(jié)果的獨(dú)立單元。
一個(gè)Document的組成是列,叫做Field。Document可以通過add方法根據(jù)需要增加列。
首先,Lucene使用分詞器對(duì)經(jīng)過預(yù)處理的純文本字節(jié)流進(jìn)行分詞;然后,調(diào)用Document類的add方法生成field實(shí)例,創(chuàng)建文檔;最后,使用IndexWriter將Document寫入索引庫。
2.1 中文分詞器的選擇
中文文本中詞和詞之間不像英文一樣存在邊界,所以中文分詞是一個(gè)專業(yè)處理中文搜索引擎中首先應(yīng)該面對(duì)的問題。
Lucene提供了一些分詞技術(shù),如按字符間空格進(jìn)行分詞的WhiteSpaceAnalyzer,按停用詞劃分的StopAnalyzer和使用更普遍的StandardAnalyzer,但是這些分詞方法都基本是針對(duì)西方文字開發(fā)的。以“我愛計(jì)算機(jī)”為例,使用StandardAnalyzer的分詞結(jié)果為“我/愛/計(jì)/算/機(jī)”,顯然這種單字劃分的方式是不準(zhǔn)確的。
在這里,我們采用SmartChineseAnalyzer分詞器,該分詞器專為中文設(shè)計(jì),分詞效果“我/愛/計(jì)算機(jī)”比較理想,而且其本身在Lucene工具包中已經(jīng)實(shí)現(xiàn),所以本系統(tǒng)直接采用SmartChineseAnalyzer進(jìn)行分詞,解決了中文分詞問題。
2.2 創(chuàng)建索引庫
對(duì)文本進(jìn)行中文分詞等分析之后,就可以創(chuàng)建索引庫。核心代碼如下:
(1)創(chuàng)建Directory
(2)創(chuàng)建IndexWriter
(3)創(chuàng)建document對(duì)象
(4)為document添加field對(duì)象
(5)調(diào)用add方法,為document添加”class” filed,其他field類似
(6)使用完成后需要將writer進(jìn)行關(guān)閉
用戶在Web接口中輸入查詢的關(guān)鍵詞,然后發(fā)出搜索請(qǐng)求,由搜索查詢服務(wù)其解析查詢請(qǐng)求,通過Lucene的核心類IndexSearch完成搜索功能,經(jīng)過處理返回給用戶。本系統(tǒng)實(shí)現(xiàn)了如下兩個(gè)方面。
3.1 IndexSearch類實(shí)現(xiàn)搜索
用戶的搜索請(qǐng)求被分詞后,調(diào)用Lucene的檢索器IndexSearch進(jìn)行搜索,返回Topdocs類。核心代碼如下。
(1)創(chuàng)建Directory
(2)創(chuàng)建IndexReader
(3)根據(jù)IndexWriter創(chuàng)建IndexSearcher
(4)創(chuàng)建parser用來確定搜索的內(nèi)容,第二個(gè)參數(shù)表示搜索的域
(5)根據(jù)Searcher返回TopDocs
(6)根據(jù)TopDocs獲取ScoreDoc
(7)根據(jù)Searcher和ScoreDoc獲取搜索到的document對(duì)象
(8)根據(jù)document對(duì)象獲取查詢的字段
(9)關(guān)閉reader
(10)返回搜索結(jié)果
3.2 關(guān)鍵詞高亮顯示
自定義一個(gè)關(guān)鍵詞高亮顯示函數(shù)displayHTMLHight。核心代碼如下。
(1)設(shè)置中文分詞器為SmartChineseAnalyzer(2)設(shè)置高亮標(biāo)簽,可以自定義
(3)創(chuàng)建QueryScorer,對(duì)query進(jìn)行評(píng)分
(4)創(chuàng)建Fragmenter,對(duì)原始信息進(jìn)行切片處理,選擇最有價(jià)值的信息進(jìn)行高亮處理
(5)創(chuàng)建高亮分析器,根據(jù)formatter和scorer選擇最有價(jià)值的信息進(jìn)行高亮處理
為了使用戶從服務(wù)器上獲取網(wǎng)頁內(nèi)容,還要客戶端與服務(wù)端進(jìn)程建立連接。UDP和TCP的通信采用Socket方法連接。本系統(tǒng)使用Socket流式通信,實(shí)現(xiàn)了客戶端和服務(wù)端的通訊功能。
4.1 Java實(shí)現(xiàn)服務(wù)器端
(1)首先創(chuàng)建一個(gè)ServerSocket對(duì)象,并為運(yùn)行該語句的計(jì)算機(jī)的指定端口建立一個(gè)監(jiān)聽服務(wù),這里綁定端口號(hào)為5678。
(2)為了隨時(shí)監(jiān)聽可能的客戶端請(qǐng)求,還要執(zhí)行語句Socket client=server.accept();使Server處于等待狀態(tài),直到捕獲到一個(gè)來自客戶端的請(qǐng)求,并返回一個(gè)用于與該客戶端通信的client對(duì)象。
(3)in為接受的客戶端請(qǐng)求
(4)out為將要返回客戶端的搜索結(jié)果
(5)調(diào)用IndexSearch函數(shù),返回搜索結(jié)果,并發(fā)送給客戶端
(6)刷新,提高IO吞吐率
(7)監(jiān)聽結(jié)束后,需要關(guān)閉client對(duì)象
4.2 PHP實(shí)現(xiàn)客戶端
為了使用戶可以通過外網(wǎng)使用搜索查詢服務(wù),本系統(tǒng)采用PHP的Socket通信。關(guān)鍵操作如下。
(1)首先,建立兩個(gè)變量來保存服務(wù)器的IP地址和端口。
(2)在服務(wù)器端可以使用set_time_out()函數(shù)來確保PHP在等待客戶端連接時(shí)不會(huì)超時(shí).。
(3)使用socket_creat()函數(shù)創(chuàng)建一個(gè)Socket,這個(gè)函數(shù)返回一個(gè)Socket句柄,這個(gè)句柄將用在以后所有的函數(shù)中。其中“AF_INET”“SOCK_STREAM”“SOL_TCP”為指定創(chuàng)建//IPV4網(wǎng)絡(luò)協(xié)議的、流式的、TCP類型的Socket。
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_ TCP);
(4)通過socket_connet函數(shù)綁定Socket到指定的IP和端口,與服務(wù)器建立連接。
$result = socket_connect($socket, $ip, $port);
$cont = $_GET[“search”];
(5)將用戶的搜索內(nèi)容$cont從UTF-8轉(zhuǎn)為GB2312,并保存為$in。這就是要發(fā)送到服務(wù)器端的內(nèi)容。
$in = iconv(“utf-8”,”gb2312//IGNORE”,$cont).” n”;$out =‘’;
(6)通過socket_write函數(shù)向服務(wù)器發(fā)送搜索請(qǐng)求。
if(!socket_write($socket, $in, strlen($in))) {
echo“socket_write() failed: reason:“ .“ ”;
}
(7)通過socket_read()函數(shù)接受服務(wù)器的搜索結(jié)果,將搜索結(jié)果從UTF-8轉(zhuǎn)化為GB2312
保存為$out并輸出,將搜索結(jié)果展現(xiàn)給用戶。
$out = socket_read($socket,1024
(8)關(guān)閉Socket對(duì)象
socket_close($socket);
通過建立索引庫,搜索查詢服務(wù)器,以及Web交互,我們基本實(shí)現(xiàn)了搜索引擎的核心功能,建立了具有中文分詞和關(guān)鍵詞高亮顯示功能的中文搜索引擎系統(tǒng)??傮w來講,該中文搜索引擎具有很好的可維護(hù)性和可擴(kuò)展性,可以在此基礎(chǔ)上開發(fā)適應(yīng)不同業(yè)務(wù)需求的搜索引擎,如在本系統(tǒng)的基礎(chǔ)上進(jìn)行二次開發(fā)的簡體中文版兒童搜索引擎。
[1]吳娛.中文搜索引擎的現(xiàn)狀與展望[J].現(xiàn)代情報(bào),1999,(3):40-44.
[2]姜元爽,譚培,劉馨元,呂加國.基于Lucene的垂直搜索引擎的設(shè)計(jì)與實(shí)現(xiàn)[J].福建電腦, 2015,31(12):21-22.
Design and implementation of Chinese search engine based on Lucene and Socket communication
Cao Shulin, Lv Qingsong,Wang Yifan,Yin Qian,Zheng Xin
(School of information science and technology, Beijing Normal University,Beijing, 100875)
Lucene is a full-text search engine toolkit written in Java, an object-oriented, multi-tier package that provides a low-coupling, platform-independent and full-text search engine architecture. The network programming based on streaming Socket is an effective method to design the network communication program. Based on Lucene, this paper designs and implements the Chinese search engine by using Chinese word segmentation technology. At the same time, it uses Java and PHP Socket network programming technology to realize the function of using Lucene service through PHP website.
Chinese search engine; Lucene; Socket; Chinese word segmentation; java; PHP
尹乾
國家自然科學(xué)基金(No.61472043)。