Lucence
jar包
commons-io-2.4.jar
IKAnalyzer2012FF_u1.jar
junit-4.9.jar
lucene-analyzers-common-4.10.3.jar
lucene-core-4.10.3.jar
lucene-queryparser-4.10.3.jar
流程:
1、創建索引並寫入索引庫中
publicclassIndexSearchTest {
// 存儲文檔對象,文檔對象還總包含域
List<Document>docs = newArrayList<>();
@Test
publicvoidIndexCreateTest() throwsIOException {
Filedir= newFile("/home/lxj/文檔/參考資料/searchsource");
for(Filef:dir.listFiles()){
StringfileName= f.getName();
StringfileContext= FileUtils.readFileToString(f);
LongfileSize= FileUtils.sizeOf(f);
// 文檔對象
Documentdoc= newDocument();
/*
* 第一個參數:域名
* 第二個參數:值
* 第三個參數:是否存儲,Store.YES、Store.NO
*/
TextFieldnameField= newTextField("fileName",fileName,Store.YES);
TextFieldcontextField= newTextField("fileContext",fileContext,Store.YES);
TextFieldsizeField= newTextField("fileSize",fileSize.toString(),Store.YES);
doc.add(nameField);
doc.add(contextField);
doc.add(sizeField);
docs.add(doc);
}
/*
* 將文檔放入磁盤,並將文檔的內容進行分詞
* 標準分詞器,對英文很好,中文,單個字就是一個詞
*/
Analyzeranalyzer= newStandardAnalyzer();
// 指定索引和文檔存儲目錄
Directorydirectory= FSDirectory.open(newFile("/home/lxj/luke/dic"));
// 創建寫對象初始化對象
IndexWriterConfigconfig= newIndexWriterConfig(Version.LUCENE_4_10_3,analyzer);
// 創建索引寫對象
IndexWriteriWriter= newIndexWriter(directory,config);
// j將文檔加入索引和文檔的寫對象中
for(Documentd:docs){
iWriter.addDocument(d);
}
iWriter.commit();
iWriter.close();
}
}
luke的使用
控制檯模式下
輸入java-jar lukeall-4.10.3.jar ,然後在path下輸入索引庫的位置
索引庫:放索引的文件夾,自行創建。
filed:域
document:文檔
term:詞元,lucence中最小的單位。
2、從索引庫中讀取相關的值
流程:
待完善。。。。。。
@Test
publicvoidtestSearch() throwsIOException, ParseException {
// 創建與寫入相同的分詞器
Analyzeranalyzer= newStandardAnalyzer();
// 創建查詢對象,第一個是默認搜索域,第二是分詞器
QueryParserqueryParser= newQueryParser("fileContext",analyzer);
// 查詢語法域名:關鍵詞相當於sql
Queryquery = queryParser.parse("fileName:apache");
// 指定索引庫目錄
Directorydir= FSDirectory.open(newFile("/home/lxj/luke/dic"));
// 創建索引讀取對象
IndexReaderiReader= IndexReader.open(dir);
// 創建索引的搜索對象
IndexSearchersearcher= newIndexSearcher(iReader);
// 搜索,參數:第一個是查詢語句對象,第二個指定顯示多少條
TopDocs topDocs= searcher.search(query,10);
// 錯搜索結果獲取結果集
ScoreDoc[]scoredocs= topDocs.scoreDocs;
System.out.println("=-====一共查詢到+"+topDocs.totalHits+"記錄=====");
for(ScoreDocsd:scoredocs){
// 獲取ID
intdocId= sd.doc;
// 通過ID獲取對應的文檔
Documentdoc= iReader.document(docId);
// 根據域名獲取對應的值
System.out.println("=====fileName:"+doc.get("fileName"));
System.out.println("=====fileSize:"+doc.get("fileSize"));
}
iReader.close();
}
3、域的詳細介紹
是否分詞
分詞的目的是爲了索引
需要分詞:文件名稱,文件內容
不需要分詞:不需要索引的域,分詞後無意義的域不需要分詞,比如身份證號。
是否索引
需要搜索的域一定要索引,
索引:文件名稱、文件內容、身份證號、
不需要索引的:圖片地址不需要創建索引,圖片地址搜索無意義。
是否存儲
是否存儲看個人需要,存儲就是document內容存入磁盤中。如果需要馬上顯示存入document中查詢顯示速度快,如果不是馬上顯示出來,則不存儲,額外佔用磁盤,不划算。
域的各種類型:
4、中文分詞
StandardAnalyzer:
單字分詞:就是按照中文一個字一個字地進行分詞。如:“我愛中國”,
效果:“我”、“愛”、“中”、“國”。
CJKAnalyzer
二分法分詞:按兩個字進行切分。如:“我是中國人”,效果:“我是”、“是中”、“中國”“國人”。
上邊兩個分詞器無法滿足需求。
SmartChineseAnalyzer
對中文支持較好,但擴展性差,擴展詞庫,禁用詞庫和同義詞庫等不好處理
使用IK_Analyzer進行分詞
// 創建索引庫
Directory dir= FSDirectory.open(newFile("/home/lxj/luke/dic"));
// 創建寫對象配置對象
IndexWriterConfigconfig= newIndexWriterConfig(Version.LUCENE_4_10_3,newIKAnalyzer());
// 創建寫對象
IndexWriteriWriter = newIndexWriter(dir, config);
擴展詞庫和禁用詞庫
<?xmlversion="1.0"encoding="UTF-8"?>
<!DOCTYPEpropertiesSYSTEM"http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>IKAnalyzer 擴展配置</comment>
<!--用戶可以在這裏配置自己的擴展字典
<entrykey="ext_dict">ext.dic;</entry>
-->
<!--用戶可以在這裏配置自己的擴展停止詞字典-->
<entrykey="ext_stopwords">stopword.dic;</entry>
</properties>
5、刪除
@Test
publicvoidIndexDel() throwsIOException {
// 索引庫
Directorydir= FSDirectory.open(newFile("/home/lxj/luke/dic"));
// 創建寫對象
IndexWriterwriter= newIndexWriter(dir,newIndexWriterConfig(Version.LUCENE_4_10_3,newIKAnalyzer()));
// 刪除所有
// writer.deleteAll();
// Term就是一個詞,第一個參數:域名,第二個就是詞的域中含有關鍵詞的數據
writer.deleteDocuments(newTerm("fileName","apache"));
writer.commit();
writer.close();
}
6、使用TermQuery進行查詢,相比
別的不變,之前使用QueryPaser進行查詢,這種方式多了一個默認的搜索域。
publicvoidTermQuery() throwsIOException {
// 索引庫
Directory dir= FSDirectory.open(newFile("/home/lxj/luke/dic"));
// reader對象
IndexReaderreader= IndexReader.open(dir);
// 創建seracher對象
IndexSearchersearcher= newIndexSearcher(reader);
// 創建TermQuery對象
org.apache.lucene.search.TermQueryteQuery= neworg.apache.lucene.search.TermQuery(newTerm("fileName","java"));
// 獲取搜索集
TopDocstopdocs= searcher.search(teQuery,10);
// 獲取結果接
ScoreDoc[]docs= topdocs.scoreDocs;
for(ScoreDocdoc:docs){
// doc是一個文件的ID
Document document= reader.document(doc.doc);
System.out.println(document.get("fileName"));
System.out.println(document.get("fileSize"));
}
}
7、使用數字範圍查詢
publicvoidNumericRangeQuery()throwsIOException {
// 索引庫
Directory dir= FSDirectory.open(newFile("/home/lxj/luke/dic"));
// reader對象
IndexReaderreader= IndexReader.open(dir);
// 創建seracher對象
IndexSearchersearcher= newIndexSearcher(reader);
// 使用數值範圍查詢
Queryquery= org.apache.lucene.search.NumericRangeQuery.newLongRange("fileSize",100L, 1000L, true,true);
// 獲取搜索集
TopDocstopdocs= searcher.search(query,10);
// 獲取結果接
ScoreDoc[]docs= topdocs.scoreDocs;
for(ScoreDocdoc:docs){
// doc是一個文件的ID
Document document= reader.document(doc.doc);
System.out.println(document.get("fileName"));
System.out.println(document.get("fileSize"));
}
}
8、使用BooleanQuery進行多條件查詢
// 索引庫
Directory dir= FSDirectory.open(newFile("/home/lxj/luke/dic"));
// reader對象
IndexReaderreader= IndexReader.open(dir);
// 創建seracher對象
IndexSearchersearcher= newIndexSearcher(reader);
// 使用數值範圍查詢
Queryquery= org.apache.lucene.search.NumericRangeQuery.newLongRange("fileSize",100L, 2000L, true,true);
// 創建TermQuery對象
org.apache.lucene.search.TermQueryteQuery= neworg.apache.lucene.search.TermQuery(newTerm("fileName","java"));
// 組合查詢文件中包含Java,文件大小在100到1000之間的
org.apache.lucene.search.BooleanQuerybQuery= neworg.apache.lucene.search.BooleanQuery();
// Occur.MUST是並且的&o的意思should是或的意思, must_not是非的意思
bQuery.add(teQuery,Occur.MUST);
bQuery.add(query,Occur.MUST);
// 獲取搜索集
TopDocstopdocs= searcher.search(bQuery,10);
// 獲取結果接
ScoreDoc[]docs= topdocs.scoreDocs;
for(ScoreDocdoc:docs){
// doc是一個文件的ID
Document document= reader.document(doc.doc);
System.out.println(document.get("fileName"));
System.out.println(document.get("fileSize"));
}
}
@Test
publicvoidNumericRangeQuery() throwsIOException {
// 多個查詢進行組合查詢
// 索引庫
Directory dir= FSDirectory.open(newFile("/home/lxj/luke/dic"));
// reader對象
IndexReaderreader= IndexReader.open(dir);
// 創建seracher對象
IndexSearchersearcher= newIndexSearcher(reader);
// 使用數值範圍查詢
Queryquery= org.apache.lucene.search.NumericRangeQuery.newLongRange("fileSize",100L, 2000L, true,true);
// 獲取搜索集
TopDocstopdocs= searcher.search(query,10);
// 獲取結果接
ScoreDoc[]docs= topdocs.scoreDocs;
for(ScoreDocdoc:docs){
// doc是一個文件的ID
Document document= reader.document(doc.doc);
System.out.println(document.get("fileName"));
System.out.println(document.get("fileSize"));
}
}
9、MutiFieldsQuery查詢
使用多個域進行查詢
publicvoid MultiFieldQueryTest() throwsIOException, ParseException {
// 多個域查詢
// 索引庫
Directory dir= FSDirectory.open(newFile("/home/lxj/luke/dic"));
// reader對象
IndexReaderreader= IndexReader.open(dir);
// 創建seracher對象
IndexSearchersearcher= newIndexSearcher(reader);
// 使用數值範圍查詢
// Queryquery =org.apache.lucene.search.NumericRangeQuery.newLongRange("fileSize",100L, 2000L, true, true);
String[]fields= {"fileName","fileContent"};
MultiFieldQueryParsermultiquery= newMultiFieldQueryParser(fields,newIKAnalyzer());
Queryquery= multiquery.parse("apache");
// 獲取搜索集
TopDocstopdocs= searcher.search(query,10);
// 獲取結果接
ScoreDoc[]docs= topdocs.scoreDocs;
for(ScoreDocdoc:docs){
// doc是一個文件的ID
Document document= reader.document(doc.doc);
System.out.println(document.get("fileName"));
System.out.println(document.get("fileSize"));
}
}