十年網(wǎng)站開(kāi)發(fā)經(jīng)驗(yàn) + 多家企業(yè)客戶(hù) + 靠譜的建站團(tuán)隊(duì)
量身定制 + 運(yùn)營(yíng)維護(hù)+專(zhuān)業(yè)推廣+無(wú)憂售后,網(wǎng)站問(wèn)題一站解決
用lucene檢索包,很強(qiáng)大。到官網(wǎng)下一個(gè)最新版本就可以進(jìn)行二次開(kāi)發(fā)。
創(chuàng)新互聯(lián)專(zhuān)注于企業(yè)成都全網(wǎng)營(yíng)銷(xiāo)推廣、網(wǎng)站重做改版、東光網(wǎng)站定制設(shè)計(jì)、自適應(yīng)品牌網(wǎng)站建設(shè)、HTML5、商城網(wǎng)站建設(shè)、集團(tuán)公司官網(wǎng)建設(shè)、成都外貿(mào)網(wǎng)站建設(shè)、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁(yè)設(shè)計(jì)等建站業(yè)務(wù),價(jià)格優(yōu)惠性?xún)r(jià)比高,為東光等各大城市提供網(wǎng)站開(kāi)發(fā)制作服務(wù)。
至于中文支持,可以使用流行的中文分詞包,建議用用paoding。
import?java.io.*;
public?class?FileDemo{
public?static?void?main(String[]?args)throws?Exception{
//第一個(gè)參數(shù)是文件路徑,第二個(gè)參數(shù)是要搜索的文件擴(kuò)展名
getFile("D:\\JavaDemo",".txt");
}
private?static?void?getFile(String?pathName,?final?String?endsWith)throws?Exception{
File?file?=?new?File(pathName);
if(!file.exists())
throw?new?RuntimeException("文件不存在,你檢索個(gè)P呀。");
file.listFiles(new?FileFilter(){
public?boolean?accept(File?file){
if(file.getName().endsWith(endsWith)){
System.out.println(file.getName());
return?true;
}else
return?false;
}
});
}
}
一.???????????創(chuàng)建索引
1.一般創(chuàng)建索引的核心步驟
(1).?創(chuàng)建索引寫(xiě)入對(duì)象IndexWriter:
IndexWriter indexWriter = new IndexWriter(INDEX_STORE_PATH,new StandardAnalyzer(),create);
參數(shù)說(shuō)明:INDEX_STORE_PATH:??索引文件存放路徑
new StandardAnalyzer():?分詞工具
create:?此參數(shù)為Boolean型,true表示重新創(chuàng)建整個(gè)索引,?false?表示增量式創(chuàng)建索引。
(2).創(chuàng)建文檔模型,并用IndexWriter對(duì)象寫(xiě)入
Document doc = new Document();
Field field1 = new Field(fieldName1, fieldValue ,??Field.Store.YES, Field.Index.TOKENIZED);
doc.add(field1);
Field field2 = new Field(fieldName2, fieldValue ,??Field.Store.YES, Field.Index.TOKENIZED);
doc.add(field2);
……
indexWriter.addDocument(doc);
indexWriter.close();
參數(shù)說(shuō)明:
Document?:負(fù)責(zé)搜集數(shù)據(jù)源,它可以從不同的物理文件提取數(shù)據(jù)并放入同一個(gè)Document?中或從一個(gè)物理文件中提取出不同的數(shù)據(jù)并放入同一個(gè)Document中。
如下圖所示
? ? ? ? ? ?
Field?:用來(lái)表示不同的數(shù)據(jù)源
fieldName1:?表示field名稱(chēng)
fieldValue:??表示field?的值
Field.Store.YES,:表示是否在索引文件中完整的存儲(chǔ)該值。
在創(chuàng)建索引時(shí),有些內(nèi)容需要以摘要的形式完整地或以片段的方式顯示在頁(yè)面上,來(lái)便于用戶(hù)查找想要的記錄,那么就應(yīng)該選擇存儲(chǔ),如果不需要完整或片段的顯示就不需要存儲(chǔ)。
Field.Index.TOKENIZED?:表示是否索引和分詞。
只要是需要當(dāng)作關(guān)鍵字讓用戶(hù)查找的字段就需要建立索引。
在建立索引的過(guò)程中,如果像文章標(biāo)題、文章內(nèi)容這樣的Field,?一般是靠用戶(hù)輸入幾個(gè)關(guān)鍵字來(lái)查詢(xún)的,就應(yīng)該選擇分詞。
如果需要用戶(hù)輸入完整字符也就是精確查找才能查詢(xún)到的,例如:beanName,就可以不分詞。
Document最直觀的理解方式:
Document就相當(dāng)于我們平臺(tái)中的一個(gè)普通javaBean,,而Field?就是javaBean中的一個(gè)屬性。lucene搜索的機(jī)制就是靠搜索指定的Field的值?,來(lái)得到含有要搜索內(nèi)容的Document?集合,所以問(wèn)題的關(guān)鍵在于如何組織Document .
2.結(jié)合平臺(tái)創(chuàng)建索引的思路
(1)?經(jīng)分析搜索元素應(yīng)該由如下內(nèi)容組成(Document的屬性)
(2)?數(shù)據(jù)庫(kù)數(shù)據(jù)轉(zhuǎn)化為Document?的構(gòu)造過(guò)程:
JavaBean / Attachment?????→???(Temp Object) BaseData??→???(Finally Object) Document
分析:
要建立索引的源數(shù)據(jù)分為兩大部分:一個(gè)是數(shù)據(jù)庫(kù)數(shù)據(jù)?BeanData ,另一個(gè)是附件數(shù)據(jù)?FileData ,?這樣可以建立一個(gè)抽象類(lèi)?BaseData ,?來(lái)存放它們共有的屬性。同時(shí)為了管理這些相應(yīng)的數(shù)據(jù),在相同的等級(jí)結(jié)構(gòu)上,建立了相應(yīng)的管理類(lèi)(xxxDataManager) ,對(duì)這些數(shù)據(jù)類(lèi)的操作(建立或刪除索引)進(jìn)行管理,并用一個(gè)工廠類(lèi)(DataManagerFactory)來(lái)創(chuàng)建所需要的管理類(lèi),IndexHelper用來(lái)充當(dāng)整個(gè)索引模塊對(duì)外的接口,為了實(shí)現(xiàn)一些與平臺(tái)特定的業(yè)務(wù),特用SupportManager來(lái)提供一些額外的業(yè)務(wù)支持,索引模塊代碼結(jié)構(gòu)如下圖所示。
二.搜索索引
1.???lucene?搜索的核心步驟:
String[]??fields??=??{“title”,?“summary”,……};?????//要查找的field范圍
BooleanClause.Occur[]???flags??=??{BooleanClause.Occur.SHOULD, BooleanClause.Occur.?MUST ,……};
Query??query = MultiFieldQueryParser.parse(queryStr, fields,flags,new StandardAnalyzer());
Hits??hits??=??new??IndexSearcher(INDEX_STORE_PATH).search(query);
for (int i = 0;i hitsLength ; i++)
{
Document doc = hits.doc(i);
String title = doc.get(“title”);
String summary = doc.get(“summary”);
//?搜索出來(lái)的結(jié)果高亮顯示在頁(yè)面上
if (title != null) {
TokenStream tokenStream = analyzer.tokenStream(“title”,new StringReader(title));
String highlighterValue = highlighter.getBestFragment(tokenStream, title) ;
if(highlighterValue != null){
title = highlighterValue ;
}
//log.info("SearchHelper.search.title="+title);
}
if(summary!= null){
TokenStream tokenStream = analyzer.tokenStream(“summary”,new StringReader(summary));
String highlighterValue = highlighter.getBestFragment(tokenStream, creator) ;
if(highlighterValue != null){
summary = highlighterValue ;
}
//log.info("SearchHelper.search. summary ="+ summary);
}
}
2.結(jié)合平臺(tái)構(gòu)造搜索模塊
PageData?類(lèi)用來(lái)存放檢索結(jié)果集數(shù)據(jù)。
PageInfo?類(lèi)用來(lái)存放頁(yè)面相關(guān)信息例如,PageData對(duì)象集合、總記錄個(gè)數(shù)、每一頁(yè)的記錄數(shù)、?總頁(yè)面數(shù)量等等。
SearchHelper用來(lái)充當(dāng)整個(gè)搜索模塊的對(duì)外接口。
三.為平臺(tái)組件添加索引的步驟(以知識(shí)中心為例)
1.在com.cscec.oa.searchengine.extend.module?目錄下添加一個(gè)新的package
例如:com.cscec.oa.searchengine.extend.module.resourcestore
2.在新的目錄下建立data package?并建立相應(yīng)的數(shù)據(jù)類(lèi),并使這個(gè)數(shù)據(jù)類(lèi)繼承BeanData。
例如:
package com.cscec.oa.searchengine.extend.module.resourcestore.data
public class ResourceStoreBeanData extends BeanData{
}
3.?與data package?同一級(jí)目錄建立manager package?并建立相應(yīng)管理類(lèi),并使這個(gè)管理類(lèi)繼承BeanDataManager
例如:
com.cscec.oa.searchengine.extend.module.resourcestore.manager
public class ResourceStoreBeanDataManagerImpl extends BeanDataManager{
}
4.以管理員的身份登陸OA后,在菜單中找到“索引模塊管理”鏈接,將相應(yīng)信息添加完成后,便可以在List?頁(yè)面?點(diǎn)擊“創(chuàng)建索引”對(duì)該模塊的數(shù)據(jù)進(jìn)行索引的建立,建立完成后便可以進(jìn)行查詢(xún)。