搜索引擎知識總結
1:搜索引擎按原理和工作方式可分爲:
A:爬蟲式,主要用Socket實現,基於TCP/IP協議
B:目錄索引式,以早期的yahoo爲代表
C:元搜索引擎,即將多個搜索引擎的結果合併返回
2:按領域範圍可分爲:
A:通用搜索引擎---針對全互聯網全部網站和各種數據信息,信息全,領域廣
B:垂直搜索引擎---針對果某一行業,如企業庫搜索,供求信息搜索,房產搜索等
3:信息類型分類:
二進制的文檔,音頻,視頻,圖片等。其中常見的二進制文檔有:TXT,WORD,EXCEL,PPT,PDF,XML,HTML
4:著名的搜索引擎列表
A:Google,出現於1998年10月,由拉里.佩奇和謝爾蓋.布林開創
B:AltaVista,用戶需要熟悉搜索的各個選項,以得到更精確的結果
C:Yahoo,1994年4月發佈,由美籍華人楊志遠和David Filo共創,早期以第一代搜索引擎爲主,人工輸入,形成龐大的目錄庫,現在則是第二代搜索引擎,自動搜索並加入數據庫
D:Baidu,2000年1月,由李彥宏開創
E:Sohu開創“搜狗”
F:Sina開創“愛問”
G:北大天網搜索
H:騰迅2006年成立“SOSO”
I:網易於2007年推出了自己的“網易有道”
------垂直搜索引擎------
A:奇虎論壇搜索
B:酷迅生活搜索
C:258商業搜索
D:去哪旅遊搜索
E:職友網搜索
5:搜索引擎研究網站
A:數據挖掘研究院---http://www.dmresearch.net
B:哈工大語言技術網---http://www.langtech.org.cn
C:車東的博客---http://www.chedong.com
D:Google黑板報---http://googlechinablog.com
E:搜狗實驗室---http://www.sogou.com/labs/
F:Search Engine Watch,這是全球最大的搜索引擎研究站---http://searchenginewatch.com
6:搜索引擎算法
A:深度優先算法,B:廣度優先算法,C:IP段掃描算法
更多的請參考:http://hi.baidu.com/chenhaoxian/blog/item/26d7560f14b69f2f6059f394.html
7:網頁分析過程
單詞提取->標點符號去除->大小寫轉換->超高頻詞彙去除->中文分詞->提取URL,EMAIL,真正意文的文本信息等
8:信息檢索模型分類
A:布爾模型,B:向量模型,C:概率模型,D:混合模型等
9:搜索引擎通常要解決的基本問題
A:信息抓取,B:數據解析,C:索引創建,D:執行檢索
10:你要知道什麼叫“倒排索引”
以字或詞做爲索引,非常適合“關鍵詞”搜索
11:當前主流的索引技術
A:倒排索引
B:反綴數組
C:簽名文件
------------------------------------------------------------------------------------------------------------
Lucene常識總結
12:Lucene中的分詞方法
(1)單詞切分
A:對於English和Chinese,我們用StandardAnalyzer就可以了
B:ChineseAnalyzer
(2)二分法
對於中文,可用CJKAnalyzer,NGram(綜合了單詞切分和二分法)
注:StandardAnalyzer,ChineseAnalyzer,CJKAnalyzer,NGram相關的jar包在:
%LUCENE%/contrib/analyzers/lucene-analyzer-2.1.0.jar包中,視版本不同而異
(3)詞典法
如IK分詞器,實現了正反向全切分算法,它包括了兩個分析器,MIK_CAnalyzer使用最大全切分算法和IKAnalyzer使用細粒度全切分算法,相關jar包爲:IKAnalyzer.jar
(4)語義法
(5)基於詞庫,如JE分詞器,可以向詞庫中添加新詞,查看詞,刪除詞,相關jar包爲:je-analysis-1.5.1.jar
Plus:中科院有個分詞器,是dll形式,在Java中必須藉助JNI,這樣效率和效果都不好,容易死機,不建議採用
(6)好了,說了這麼多分詞器,最後推薦大家用JE分詞器,足夠了
13:常用二進制文檔解析組件
A:PDF---PDFBox,從http://sourceforge.net/projects/pdfbox/下載PDFBox類庫並解壓,將external和lib下的jar包全copy到你的應用程序/lib下
B:WORD---用POI的一個組件包,textmining,從http://mirrors.ibiblio.org/pub/mirrors/maven2/org/textmining/tm-extractors/0.4/下載tm-extractors-0.4.zip
C:EXCEL---JExcel,從http://www.andykhan.com/jexcelapi/下載
D:XML---DOM4J,從http://www.dom4j.org/下載
E:HTML---HTMLParser,從http://htmlparser.sourceforge.net/下載,我們需要filterbuilder.jar,htmlparser.jar,htmllexer.jar,thumbelina.jar
F:Lius,用於從各種文檔中提取文本信息,只是對PPT文檔,只能解析出英文
注:推薦使用Lius,
14:索引創建方式
靜態索引,動態索引(增量索引)
IndexWriter indexWriter = new IndexWriter(indexPath, new SimpleAnalyzer(), false);
第三個參數的意思就是:是否覆蓋原來的索引,false時爲增量索引
15:索引結構:
多文件索引,複合索引
調用indexWriter.useCompoundFile(false),爲多文件索引,默認true爲附和索引
多文件索引時,會創建很多的文件,在打索引開時,會佔用大量的文件句柄資源,造成系統響應慢。而複合索引則會成n倍的減少文件數量,但是,統一文件存儲大量數據會造成數據更新比較慢
16:建議不用IndexModifier,它在close時並沒有真正刪除Document,最好自己封裝IndexWriter和IndexReader
17:不要過度使用“過濾器”,會有不小的性能開銷
18:Lucene的邏輯組成,個人理解
lucene索引由多個“索引塊”(segment)組成,增量索引以新塊形式出現,每個“索引塊”由多個“文檔”(document)組成,每個“文檔”由多個“索引域”(field)組成,“分析器”對每個“索引域”進行分析,拆分成很多“索引項”,最終構成了lucene的索引
19:Lucene的物理組成,個人理解
A:通常所說的索引指的是:在某個目錄下的所有索引文件
B:多文件索引在創建時,至少會有fdt,fdx,fnm,frq,nrm,prx,tii,tis(這8個可以稱爲一個索引段)和segments.gen,segments_*10(這兩個爲獨一的)文件,可以有單段多文件索引,也可以有多段多文件索引
C:複合索引在創建時,會將以上8個文件合併,形成一個cfs文件,再加個兩個獨一的文件,所以,它也有單段複合索引和多段複合索引兩種
D:此外,多文件索引和複合索引還可以共存,但只有兩個獨一文件
E:最後我們通過IndexWriter.optimize(),對所有的文件進行優化成3個文件,cfs,segments.gen和segments_*
------------------------------------------------------------------------------------------------------------
實用分類總結
20:我們大至可以分爲:
A:索引的建立和優化
B:索引的管理
C:解析用戶請求
D:組合多條件搜索
E:過濾結果,進行排序,高亮處理等
21:索引建立和優化
一:建立
(1)增量索引:IndexWriter indexWriter = new IndexWriter(indexPath, new SimpleAnalyzer(), false);
(2)複合索引:indexWriter.useCompoundFile(true)
(3)Field參數含義,Field field = new Field(名稱,內容,存儲方式,索引方式);
存儲方式有三種:Field.Store.NO(不存儲),Field.Store.YES(存儲),Field.Store.Compress(壓縮存儲)
索引方式有四種:Field.Index.NO(不索引),Field.Index.TOKENIZED(分詞並索引),Field.Index.UN_TOKENIZED(不分詞索引),Field.Index.NO_NORMS(禁用分析器處理)
(4)對不同文檔Document使用不同分析器indexWriter.addDocument(doc,new StandardAnalyzer());
(5)限制Field詞條數量,indexWriter.setMaxFieldLength(200);
(6)由於lucene採用統一的文檔形式,所以對於非格式文本我們需要提前格式化,如數字和時間,最好定長表示,不足的用0補充,以保證檢索和排序的正確性
二:優化
(1)利用緩存,減少磁盤讀寫頻率
A:indexWriter.setMergeFactor(10),每10個document合併爲一個索引塊,每10個索引塊合併成一個大索引塊,每10個大索引塊合併成更大的索引塊,依次類推
B:indexWriter.setMaxBufferedDocs(100),用更多的內存換取更快的索引
C:先建立內存索引,再寫入磁盤,用RAMDirectory
D:用indexWriter.optimize()自身優化
(2)減少索引文件數量和大小
22:索引的管理
A:瞭解索引本身信息,我們需要了解HITS,HIT,Document各自的屬性和方法,請參照相應的API
B:索引的刪除,添加,更新(本質是先刪除,後添加)
創建表態索引用和增量索引用:IndexWriter
刪除和添加索引用:IndexReader
用IndexReader刪除某個Document,只是做了刪除標記,不參與檢索,要用IndexWriter.optimize()將其物理刪除
C:不同目錄的索引合併,用indexWriter.addIndexes(Directory directory),先把其中一個索引讀入內存後優化,再用此方法加入到另一FSDirectory參數的indexWriter中,優化並關閉,這樣這實現了兩個索引的合併
D:推薦用Luke,是一套lucene索引管理的軟件
23:解析用戶請求
A:自己寫程序分析,提取用戶輸入的關鍵字
B:用lucene自己的QueryParser解析,默認是OR邏輯
24:組合多條件搜索
A:用BooleanQuery可以實現“多索引域”搜索
B:MultiSearcher雖然可以多索引搜索,但實質還是一個一個順序進行的,可以用ParallelMultiSearcher實現多線程多索引搜索
C:在BooleanQuery中,不能只含有BooleanClause.Occur.MUST_NOT,否則,只會返回空的結果集
D:組合用QueryParser,TermQuery,BooleanQuery,RegexQuery足以滿足檢索需求,如下:
- String indexPath = "你的索引目錄";
- String word_list[] = {"中國","北京"};
- String feild_list[] ={"feild_a","feild_b"};
- IndexSearcher indexSearcher = new IndexSearcher(indexPath);
- Analyzer analyzer = new StandardAnalyzer();
- BooleanQuery boolQuery = new BooleanQuery();
- for(int i = 0;i < 2;i++){
- QueryParser parser = new QueryParser(feild_list[i],analyzer);
- Query query = parser.parse(word_list[i]);
- boolQuery.add(query,BooleanClause.Occur.SHOULD);
- }
- //以上實現了對用戶輸入的數據實現了lucene自帶的QueryParser解析
- //同時在相應的feild_a和feild_b索引域附進行檢索
- Term ta = new Term("date","20090101");
- Term tb = new Term("date","20090131");
- RangeQuery rangeQuery = new RangeQuery(ta,tb,true);
- //日期以年月日方式,定才存儲,這樣纔可以得到正確結果,true表示包括邊界
- boolQuery.add(rangeQuery,BooleanClause.Occur.MUST);
- Hits hits = indexSearcher.search(boolQuery);
String indexPath = "你的索引目錄";
String word_list[] = {"中國","北京"};
String feild_list[] ={"feild_a","feild_b"};
IndexSearcher indexSearcher = new IndexSearcher(indexPath);
Analyzer analyzer = new StandardAnalyzer();
BooleanQuery boolQuery = new BooleanQuery();
for(int i = 0;i < 2;i++){
QueryParser parser = new QueryParser(feild_list[i],analyzer);
Query query = parser.parse(word_list[i]);
boolQuery.add(query,BooleanClause.Occur.SHOULD);
}
//以上實現了對用戶輸入的數據實現了lucene自帶的QueryParser解析
//同時在相應的feild_a和feild_b索引域附進行檢索
Term ta = new Term("date","20090101");
Term tb = new Term("date","20090131");
RangeQuery rangeQuery = new RangeQuery(ta,tb,true);
//日期以年月日方式,定才存儲,這樣纔可以得到正確結果,true表示包括邊界
boolQuery.add(rangeQuery,BooleanClause.Occur.MUST);
Hits hits = indexSearcher.search(boolQuery);
由此,我們可以實現,在用lucene自身QueryParser的前提下,
D-1:同一“索引域”中檢索不同關鍵字
D-2:同一“索引域”中檢索同一關鍵字
D-3:不同“索引域”中檢索不同關鍵字
D-4:不同“索引域”中檢索同一關鍵字
是不是夠你一般的實際檢索了!!
25:檢索結果的過濾
A:QueryFilter帶有緩存,其它的RangeFilter,PrefixFilter,ChainedFilter都不帶有緩存,要用CachingWrapperFilter包裝纔可
B:儘量不用過濾器
C:兩種過濾方式,一種是在搜索結果提取出來後過濾,另一種是把過濾條件加在搜索條件中,後者是其於前者的,由此可見,在搜索前加入太多搜索條件對性能有很大的影響,在有必要更精確的搜索時,還是建議使用前者吧
26:對檢索結果進行排序
A:默認排序規則:得分-->時間
B:對多字段排序,如下
- SortField sf1 = new SortField("id",false);//升序
- SortField sf2 = new SortField("date",true);//降序
- SortField fields[] = new SortField[]{sf1,sf2};
- Sort sort = new Sort(fields);
- Hits hits = searcher.search(q,sort);//q是一個TermQuery
SortField sf1 = new SortField("id",false);//升序
SortField sf2 = new SortField("date",true);//降序
SortField fields[] = new SortField[]{sf1,sf2};
Sort sort = new Sort(fields);
Hits hits = searcher.search(q,sort);//q是一個TermQuery
27:關於高亮顯示
可以參照API和下面這個網址:
http://hi.baidu.com/deepeye/blog/item/83a8e8c4bec788ae8326ac5f.html
另外,我們也可以用Jquery,這個JavaScript框架來實現高亮顯示,可以參考下面這個網址
效果一:http://www.cnblogs.com/yjmyzz/archive/2008/10/19/1314494.html
效果二:http://www.webwoo.org/jquery/200811/21-28450.html
28:其它搜索引擎參考:
1:sphinx
http://dev.cgfinal.com/sphinx/sphinx.html
2:MySQL全文檢索
http://hi.baidu.com/longchengjiang/blog/item/ef9b05d32527f1083af3cf19.html
http://database.51cto.com/art/200902/111597.htm