Google搜索引擎建立至今已經(jīng)快20年了,之后全球各類(lèi)大大小小類(lèi)似的搜索引擎也陸續(xù)出現(xiàn)、消亡。國(guó)內(nèi)目前以百度為大,搜狗、360、必應(yīng)等也勢(shì)在必爭(zhēng)。搜索引擎技術(shù)也發(fā)展的相當(dāng)成熟,同時(shí)也就出現(xiàn)了很多開(kāi)源的搜索引擎系統(tǒng)。比如,Solr、Lucene、Elasticsearch、Sphinx等。
10余年的白云網(wǎng)站建設(shè)經(jīng)驗(yàn),針對(duì)設(shè)計(jì)、前端、開(kāi)發(fā)、售后、文案、推廣等六對(duì)一服務(wù),響應(yīng)快,48小時(shí)及時(shí)工作處理。成都全網(wǎng)營(yíng)銷(xiāo)的優(yōu)勢(shì)是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動(dòng)調(diào)整白云建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無(wú)論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計(jì),從而大程度地提升瀏覽體驗(yàn)。創(chuàng)新互聯(lián)從事“白云網(wǎng)站設(shè)計(jì)”,“白云網(wǎng)站推廣”以來(lái),每個(gè)客戶項(xiàng)目都認(rèn)真落實(shí)執(zhí)行。
本文以sphinx search為例來(lái)介紹如何打造自己的搜索引擎。該搜索引擎的架構(gòu)大致如下:
Sphinx search
Sphinx search 是俄羅斯人用C++寫(xiě)的,速度很快,可以非常容易的與SQL數(shù)據(jù)庫(kù)和腳本語(yǔ)言集成,內(nèi)置MySQL和PostgreSQL 數(shù)據(jù)庫(kù)數(shù)據(jù)源的支持。其官方網(wǎng)站是: http://sphinxsearch.com/
可以說(shuō)Sphinx支持包括英文、中文等所有語(yǔ)言的搜索。英文是以空格、標(biāo)點(diǎn)符號(hào)來(lái)分割單詞的,很容易切分。而中文詞匯之間是沒(méi)有空格的,很難區(qū)分,所以才有了自然語(yǔ)言處理中的“中文分詞”技術(shù)的研究。Sphinx默認(rèn)把中文按字拆分的,但這樣就會(huì)產(chǎn)生搜索出不相干的內(nèi)容來(lái)。比如,搜索“中國(guó)”,它會(huì)把同時(shí)包含“中”和“國(guó)”但不包含“中國(guó)”的文檔搜出來(lái)。因此,有人就給Sphinx打了中文分詞的補(bǔ)丁。
如果沒(méi)有搞錯(cuò)的話,最早添加中文分詞的是Coreseek,好像也是中文圈用得最廣的支持中文分詞的Sphinx,其它還有sphinx-for-chinese。然而這二者基于的Sphinx版本都太低了,有好多年沒(méi)有更新。其中存在的一些Sphinx的bug也沒(méi)有解決。
github上有一個(gè)基于Sphinx 2.2.9版本的代碼庫(kù)添加了中文分詞: https://github.com/eric1688/sphinx 經(jīng)測(cè)試,該版本穩(wěn)定性和速度都要好于coreseek。當(dāng)然它依然支持英文等其它語(yǔ)言的搜索,只是對(duì)中文搜索更加準(zhǔn)確了。
Sphinx 安裝
git clone https://github.com/eric1688/sphinx
cd sphinx
#編譯(假設(shè)安裝到/usr/local/sphinx目錄,下文同)
./configure --prefix=/usr/local/sphinx
make
sudo make install
安裝好后,在/usr/local/sphinx目錄下有以下幾個(gè)子目錄:
etc/ sphinx配置文件,不同的索引可以寫(xiě)不同的配置文件
bin/ sphinx程序,其中有建立索引的程序:indexer, 搜索守護(hù)進(jìn)程:searchd
var/ 一般用了放置indexer索引好的文件
Sphinx索引的建立
MySQL數(shù)據(jù)庫(kù)表結(jié)構(gòu)
從上面的架構(gòu)圖可以看出來(lái),我們要搜索的數(shù)據(jù)都存放在MySQL數(shù)據(jù)庫(kù)中。假設(shè)我們的數(shù)據(jù)庫(kù)名稱叫blog_data,其中有個(gè)表叫article,表結(jié)構(gòu)如下:
字段名 說(shuō)明
id 文章唯一id(主鍵)
title 文章標(biāo)題
content 文章內(nèi)容
created_time 文章創(chuàng)建時(shí)間
該article表可以是你本身網(wǎng)站的文本內(nèi)容存放的表格,也可以是你的網(wǎng)絡(luò)爬蟲(chóng)抓取到的數(shù)據(jù)存儲(chǔ)表。
還有建立另外一個(gè)表sph_counter用來(lái)存儲(chǔ)indexer已經(jīng)索引的最大doc id
字段名 說(shuō)明
counter_id 標(biāo)記是對(duì)哪個(gè)表做記錄
max_doc_id 被索引表的最大ID
note 注釋?zhuān)梢允潜砻?br/>update_at 更新時(shí)間
建立索引配置文件:
新建或修改/usr/local/sphinx/etc/blog.conf 配置文件:
source blog_main
{
type = mysql
sql_host = localhost
sql_user = reader
sql_pass = readerpassword
sql_db = blog_data
sql_port = 3306
sql_query_pre = SET NAMES utf8mb4
sql_query_pre = REPLACE INTO sph_counter SELECT 1, MAX(id), 'article', NOW() FROM article
sql_query = SELECT id, title, content, \
UNIX_TIMESTAMP(created_time) AS ctime, \
FROM article \
WHERE id <= (SELECT max_doc_id from sph_counter WHERE counter_id=1)
sql_attr_timestamp = ctime #從SQL讀取到的值必須為整數(shù),作為時(shí)間屬性
}
index blog_main
{
source = blog_main #對(duì)應(yīng)的source名稱
path = /user/local/sphinx/var/data/blog_main
docinfo = extern
mlock = 0
morphology = none
min_word_len = 1
html_strip = 0
charset_type = utf-8
chinese_dictionary = /user/local/sphinx/etc/xdict #中文分詞的詞典
ngram_len = 0
stopwords = /user/local/sphinx/etc/stop_words.utf8
}
#全局index定義
indexer
{
mem_limit = 512M
}
#searchd服務(wù)定義
searchd
{
listen = 9900
listen = 9306:mysql41 # 實(shí)時(shí)索引監(jiān)聽(tīng)的端口
read_timeout = 5
max_children = 90
max_matches = 100000
max_packet_size = 32M
read_buffer = 1M
subtree_docs_cache = 8M
subtree_hits_cache = 16M
#workers = threads?
dist_threads = 2
seamless_rotate = 0
preopen_indexes = 0
unlink_old = 1
pid_file = /usr/local/sphinx/var/log/blog_searchd_mysql.pid
log = /usr/local/sphinx/var/log/blog_searchd_mysql.log
query_log = /usr/local/sphinx/var/log/blog_query_mysql.log
}
編輯好以上配置文件,就可以開(kāi)始建立索引了:
cd /usr/local/sphinx/bin
./indexer -c ../etc/blog.conf
索引建立后,就會(huì)在var/data/下面有名稱前綴為blog_main.XXX的索引文件生成。
建立實(shí)時(shí)索引
上面的配置文件是建立一個(gè)靜態(tài)索引,把當(dāng)時(shí)數(shù)據(jù)庫(kù)里面的所有數(shù)據(jù)進(jìn)行索引。但是,你的數(shù)據(jù)庫(kù)往往是不斷增加新數(shù)據(jù)的。為了及時(shí)索引并搜索到最新加入的數(shù)據(jù),就需要配置實(shí)時(shí)索引了。
index rt_weixin {
type = rt
path = /usr/local/sphinx/var/data/rt_blog
rt_field = title
rt_field = content
rt_attr_timestamp = pubtime
ngram_chars = U+3000..U+2FA1F #為了支持中文
ngram_len = 1
}
該倉(cāng)庫(kù)代碼的作者可能是忘了給實(shí)時(shí)索引加中文分詞,如果不配置ngram_chars 參數(shù)就不能搜到中文,添加后搜索是按單字匹配的,可見(jiàn)作者確實(shí)是忘了給實(shí)時(shí)索引部分加中文分詞。
添加以上實(shí)時(shí)索引后并不能搜索到實(shí)時(shí)數(shù)據(jù)。實(shí)時(shí)索引的更新/添加只能通過(guò)SphinxQL(一個(gè)類(lèi)似MySQL的協(xié)議),所以還要寫(xiě)一個(gè)Python腳本,從數(shù)據(jù)庫(kù)讀取最新的數(shù)據(jù)并通過(guò)SphinxQL更新到實(shí)時(shí)索引。
import MySQLdb
# 連接實(shí)時(shí)索引
db_rt = MySQLdb.connect(
'127.0.0.1',
'nodb', # 對(duì)于實(shí)時(shí)索引來(lái)說(shuō),db,user,password都是不需要的,隨便寫(xiě)。
'noname',
'nopass',
port=9306, # 實(shí)時(shí)索引監(jiān)聽(tīng)的端口
)
# 向?qū)崟r(shí)索引更新數(shù)據(jù)的函數(shù)
def into_rt(index_name, item):
cursor = db_rt.cursor()
fields = item.keys()
values = item.values()
fieldstr = ','.join(fields)
valstr = ','.join(["'%s'"] * len(item))
for i in xrange(len(values)):
if isinstance(values[i], unicode):
values[i] = values[i].encode('utf8')
elif isinstance(values[i], datetime):
try:
values[i] = int(time.mktime(values[i].timetuple()))
except:
traceback.print_exc()
print values[i]
values[i] = int(time.time())
sql = 'INSERT INTO %s (%s) VALUES(%s)' % (index_name, fieldstr, valstr)
# print sql
sql = sql % tuple(values)
try:
cursor.execute(sql)
db_rt.commit()
except Exception, e:
if e[0] == 1064:
# ignore duplicated id error
pass
else:
traceback.print_exc()
raise 'realtime index error'
finally:
cursor.close()
以上是及時(shí)建立實(shí)時(shí)索引的python程序的主要部分??梢园阉O(shè)置成后臺(tái)一直運(yùn)行的守護(hù)程序,也可以在crontab里面配置每隔幾分鐘運(yùn)行一次。
索引的更新
靜態(tài)的主索引如果只建立一次,實(shí)時(shí)索引的數(shù)據(jù)量會(huì)越積越多,對(duì)實(shí)時(shí)索引的搜索帶來(lái)很大壓力,所以我們要定時(shí)重新建立主索引,清理實(shí)時(shí)索引。
清理實(shí)時(shí)索引的程序可以參考上面建立實(shí)時(shí)索引的python程序。
crontab 設(shè)置每天凌晨1點(diǎn)運(yùn)行 indexer
crontab 設(shè)置indexer運(yùn)行完畢后清理實(shí)時(shí)索引,并從新的max_doc_id開(kāi)始建立實(shí)時(shí)索引
以上就是建立一個(gè)自己的搜索引擎的過(guò)程。更多配置細(xì)節(jié)可到官方網(wǎng)站參考文檔。
文章首發(fā)于我的技術(shù)博客:www.yuanrenxue.com
文章名稱:使用sphinxsearch打造你自己的中文搜索引擎
URL地址:http://sd-ha.com/article4/pephie.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供響應(yīng)式網(wǎng)站、自適應(yīng)網(wǎng)站、用戶體驗(yàn)、網(wǎng)站策劃、軟件開(kāi)發(fā)、域名注冊(cè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)