最近要整一個站內一鍵搜索功能,正常來說,如果是在互聯網的話,可以利用百度或者谷歌的站內搜索。嘛~不過搜索不准確就是了。但是遺憾的是,我這個是在內網使用的業務系統,首先非html生成,其次應用了大量ajax動態加載數據,然後還不是那種cms的全部同意內容表content字段的數據結構。所以說存在幾個問題。
1. 爬網方式
2. 搜索實現
3. 搜索速度
然後根據能夠使用的資源,設計了以下實現思路。
1. 首先寫一個爬蟲,能夠根據配置的數據表,爬取字段,顯示名稱,以及爬取數據存儲格式等因素進行數據庫爬取。目的是想要一鍵搜索能夠搜索到的業務表都把數據按照預定義格式爬取到一個數據表中。
2. 為了實現高性能的搜索功能(當然不能夠用like之流了),這裡用到了Oracle全文索引功能。記錄下配置過程。
alter user ctxsys account unlock; grant execute on ctx_ddl to testuser;首先是啟用oracle全文索引功能,在PL/SQL創建SQL窗口執行上述命令即可。主要是啟用ctxsys用戶(全文索引用戶),然後將ctx_ddl執行權限賦予當前用戶。(能夠執行全文索引)
然後就是創建分詞器了。全文索引之所以能夠提高性能的原因,就是因為其避免了使用like這種模糊匹配。它允許用戶創建分詞器,根據索引字段內容進行分詞索引。例如,山東省濟南市,它會分別拆解成山東,山東省,濟南,濟南市然後進行索引。(當然根據你使用分詞器不同,效果有所差別,如果使用chinese_lexer那麼可能只會分成山東省,濟南市兩個)這樣你在進行查詢的時候,輸入山東,山東省,濟南,濟南市都會檢索到該記錄。但是如果你輸入“省濟南”那麼很遺憾,搜索不到,這點與like不同,要注意。不過一般也不會出現該種情況吧,除非“腦殘了?”呵呵。
分詞器創建如下:
exec ctx_ddl.create_preference ('test_lexer', 'chinese_vgram_lexer');這裡用了一個比較全的中文分詞器,嘛~分詞器這東西大家用的時候自己測試一下吧,上述這個可以滿足大多數需要了。
注意,執行時要使用PL/SQL的話,記得在新建命令窗口中執行。
如果需要的話,其實還可以創建過濾詞組,就是在系統分詞器分詞創建索引時不想要出現的分詞類型。這時候可以創建一個stoplist,如下:
exec ctx_ddl.create_stoplist('test_stoplist');然後向裡面添加過濾詞,
ctx_ddl.add_stopword('test_stoplist','公司');
ctx_ddl.add_stopword('test_stoplist','分局');
這樣在創建索引時,“測試公司”,就不會分解成“測試”,“公司”兩個詞了。當然搜索的時候,也就必須要輸入“測試公司”才能夠找到結果。
然後我們來看看創建索引的語句:
create index TEST_INDEX on TABLE_NAME(COL_NAME) indextype is CTXSYS.CONTEXT parameters('lexer test_lexer stoplist test_stoplist');當然如果沒有使用過濾詞組的話,那麼可以去除stoplist的聲明。
這樣索引就創建完成了,下面說一下如何基於索引進行查詢。
select * from TABLE_NAME where contains(COL_NAME,'測試')>0;就是通過上述方式了,其實很簡單吧。'測試'就是我們輸入的查詢關鍵字了。這裡其實還可以對測試進行分詞查詢,就類似百度那樣,需要了解的自己查詢吧。
但是現在發現一個問題,如果有新的數據插入,或者數據修改的時候,索引不會變更?bug?當然不是,因為全文索引需要占用資源較大,所以設計的時候需要手工執行更新索引的腳本才行,(當然允許自動更新,加個參數也可以實現,但是,那樣做會嚴重影響性能,並且只更新索引,不執行優化,所以還是手動更新吧)具體代碼如下:
exec ctx_ddl.sync_index('test_index') --同步索引,也就是更新索引了 exec ctx_ddl.optimize_index('test_index','full') --優化索引,類似於重建索引,會提高查詢效果但是什麼時候執行,怎麼執行呢?估計都想到了,寫個job就可以了。我定義的是每天凌晨3點執行。
基本上到這裡就差不多可以結束了。目前來看的話,通過全文索引進行查詢速度還是有相當的優勢的,比like速度快非常多,提供大家參考吧。