Lucene是apache組織的一個用java實現全文搜索引擎的開源項目。
其功能非常的強大,api也很簡單。總得來說用Lucene來進行建立
和搜索和操作數據庫是差不多的(有點像),Document可以看作是
數據庫的一行記錄,Field可以看作是數據庫的字段。用lucene實
現搜索引擎就像用JDBC實現連接數據庫一樣簡單。
Lucene2.0,它與以前廣泛應用和介紹的Lucene
Lucene2.0的下載地址是http://apache.justdn.org/lucene/java/
大家先看一個例子,通過這個例子來對
lucene
的一個大概的認識。
一個
Junit
測試用例:
(
為了讓代碼清晰好看,我們將異常都拋出
)
a)???
這是一個建立文件索引的例子
public
void
testIndexHello()
throws
IOException
??? {
??????? Date date1 =
new
Date();
?
???????
//
可以說是創建一個新的寫入工具
???????
//
第一個參數是要索引建立在哪個目錄里
???????
//
第二個參數是新建一個文本分析器,這里用的是標準的大家也可以自己寫一個
???????
//
第三個參數如果是true,在建立索引之前先將c:\\index目錄清空。
??????? IndexWriter writer =
new
IndexWriter(
"c:\\index"
,
new
StandardAnalyzer(),
true
);
???????
//?????
這個是數據源的文件夾
??????? File file =
new
File(
"c:\\file"
);
???????
/**
???????
?
*
例子主要是將C:\\file目錄下的文件的內容進行建立索引,將文件路徑作為搜索內容的附屬.
???????
?
*/
???????
???????
if
(file.isDirectory())
??????? {
??????????? String[] fileList = file.list();
???????????
for
(
int
i = 0; i < fileList.
length
; i++)
??????????? {
//?????????????
建立一個新的文檔,它可以看作是數據庫的一行記錄
??????????????? Document doc =
new
Document();
??????????????? File f =
new
File(file,
???????????????
??????? fileList[i]);
??????????????? Reader reader =
new
BufferedReader(
new
FileReader(f));
??????????????? doc.add(
new
Field(
"file"
,reader));
//
為doument添加field
??????????????? doc.add(
new
Field(
"path"
,f.getAbsolutePath(),Field.Store.
YES
,Field.Index.
NO
));
??????????????? writer.addDocument(doc);
??????????? }
???????????
??????? }
??????? writer.close();
//
這一步是必須的,只有這樣數據才會被寫入索引的目錄里
??????? Date date2 =
new
Date();
??????? System.
out
.println(
"
用時"
+(date2.getTime()-date1.getTime())+
"
毫秒"
);
}
注意:因為建立索引本來就是費時,所以說最后輸出的用時會比較長,請不要奇怪。
b)
一個通過索引來全文檢索的例子
public
void
HelloSearch()
throws
IOException, ParseException
??? {
??????? IndexSearcher indexSearcher =
new
IndexSearcher(
"c:\\index"
);
//
和上面的IndexWriter一樣是一個工具
??????? QueryParser queryParser =
new
QueryParser(
"file"
,
//
這是一個分詞器
???????????????
new
StandardAnalyzer());
??????? BufferedReader br =
new
BufferedReader(
new
InputStreamReader(System.
in
));
??????? Query query = queryParser.parse(br.readLine());
//
這個地方Query是抽象類大家也注意一下,下面會講到的
??????? Hits hits = indexSearcher.search(query);
??????? Document doc =
null
;
??????? System.
out
.print(
"
正搜索................"
);
???????
for
(
int
i = 0; i < hits.length(); i++)
??????? {
??????????? doc = hits.doc(i);
??????????? System.
out
.println(
"
內容是:"
+doc.get(
"file"
));
//
注意這里輸出的是什么
??????????? System.
out
.println(
"
文件的路徑是:"
+ doc.get(
"path"
));
??????? }
??? }
通過上面的兩個例子應該可以看出Lucene還是比較簡單的。
運行一下上面的兩個例子,大家可能會說怎么doc.get(
“
file
”
);
返回的是空呢,我們馬上會講到。
下面講一下索引的建立
其實從上面的例子就可以看出建立索引就用到Document,IndexWriter,Field。
最簡單的步驟就是:
首先分別new 一個Document,IndexWriter,Field
然后用Doument.add()方法加入Field,
其次用IndexWrtier.addDocument()方法加入Document。
最后調用一下IndexWriter.close()方法關閉輸入索引,這一步非常的重要只有調用這個方法索引才會被寫入索引的目錄里,而這是被很多初學的人所忽略的。
Document
沒有什么好介紹的,把它的作用看成數據庫中的一行記錄就行。
Field
是一個比較重要的也是比較復雜的:
看一下它的構造函數有5個:
Field
(String?name, byte[]?value, Field.Store?store)
Field
(String?name, Reader?reader)
Field
(String?name, Reader?reader, Field.TermVector?termVector)
Field
(String?name, String?value, Field.Store?store, Field.Index?index)
Field
(String?name, String?value, Field.Store?store, Field.Index?index, Field.TermVector?termVector)
在Field中有三個內部類:Field.Index,Field.Store,Field.termVector,而構造函數也用到了它們。
注意:
termVector
是Lucene 1.4
新增的它提供一種向量機制來進行模糊查詢的這個不常用,默認是false不過是什么對于一般查詢無影響。
它們的不同的組合,在全文檢索中有著不同的作用。看看下面的表吧:
Field.Index |
Field.Store |
說明 |
|
文章的標題或內容(如果是內容的話不能太長)是可以被搜索的 |
|
文章的標題或內容(內容可以很長)也是可以被看過的 |
||
這是不能被搜索的,它只是被搜索內容的附屬物。如URL等 |
||
|
不被分詞,它作為一個整體被搜索,搜一部分是搜不出來的 |
|
沒有這種用法 |
而對于
Field
(String?name, Reader?reader)
Field
(String?name, Reader?reader, Field.TermVector?termVector)
他們是Field.Index.TOKENIZED和Field.Store.NO的。這就是為什么我們在上面的例子中會出現文章的內容為null了。因為它只是被索引了,而并沒有被存儲下來。如果一定要看到文章的內容的話可以通過文章的路徑得到畢竟文章的路徑是作為搜索的附屬物被搜索出來了。而我們在Web開發的時候一般是將大數據放在數據庫中,不會放在文件系統中,更不會放在索引目錄里,因為它太大了操作會加大服務器的負擔。
下面介紹一下IndexWriter:
它就是一個寫入索引的寫入器,它的任務比較簡單:
1.
用addDocument()將已經準備好寫入索引的document們加入
2.
調用close()將索引寫入索引目錄
先看一下它的構造函數:
IndexWriter
(Directory?d, Analyzer?a, boolean?create)
(未完)
|
|||||||||||||