?
今天看看 ch3, Add search to your Application. 真正開始使用 Lucene search 來搜索你的目標(biāo)了.
1. 實(shí)現(xiàn)一個(gè)簡單的search feature
?? 在本章中只限于討論簡單Lucene 搜索API, 有下面幾個(gè)相關(guān)的類:
?Lucene 基本搜索API:
類 | 功能 |
IndexSearcher | 搜索一個(gè)index的入口.所有的searches都是通過IndexSearcher 實(shí)例的幾個(gè)重載的方法實(shí)現(xiàn)的. |
Query (and subclasses) | 各個(gè)子類封裝了特定搜索類型的邏輯(logic),Query實(shí)例傳遞給IndexSearcher的search方法. |
QueryParser | 處理一個(gè)可讀的表達(dá)式,轉(zhuǎn)換為一個(gè)具體的Query實(shí)例. |
Hits | 包含了搜索的結(jié)果.有IndexSearcher的search函數(shù)返回. |
下面我們來看幾個(gè)書中的例子:
LiaTestCase.java? 一個(gè)繼承自TestCase 并且擴(kuò)展了TestCase的類, 下面的幾個(gè)例子都繼承自該類.
01?package?lia.common;
02?
03?import?junit.framework.TestCase;
04?import?org.apache.lucene.store.FSDirectory;
05?import?org.apache.lucene.store.Directory;
06?import?org.apache.lucene.search.Hits;
07?import?org.apache.lucene.document.Document;
08?
09?import?java.io.IOException;
10?import?java.util.Date;
11?import?java.text.ParseException;
12?import?java.text.SimpleDateFormat;
13?
14?/**
15??*?LIA?base?class?for?test?cases.
16??*/
17?public?abstract?class?LiaTestCase?extends?TestCase?{
18???private?String?indexDir?=?System.getProperty("index.dir");? // 測試 index 已經(jīng)建立好了
19???protected?Directory?directory;
20?
21???protected?void?setUp()?throws?Exception?{
22?????directory?=?FSDirectory.getDirectory(indexDir,?false);
23???}
24?
25???protected?void?tearDown()?throws?Exception?{
26?????directory.close();
27???}
28?
29???/**
30????*?For?troubleshooting 為了 解決問題的方法
31????*/
32???protected?final?void?dumpHits(Hits?hits)?throws?IOException?{
33?????if?(hits.length()?==?0)?{
34???????System.out.println("No?hits");
35?????}
36?
37?????for?(int?i=0;?i?<?hits.length();?i++)?{
38???????Document?doc?=?hits.doc(i);
39???????System.out.println(hits.score(i)?+?":"?+?doc.get("title"));
40?????}
41???}
42?
43???protected?final?void?assertHitsIncludeTitle(
44???????????????????????????????????????????Hits?hits,?String?title)
45?????throws?IOException?{
46?????for?(int?i=0;?i?<?hits.length();?i++)?{
47???????Document?doc?=?hits.doc(i);
48???????if?(title.equals(doc.get("title")))?{
49?????????assertTrue(true);
50?????????return;
51???????}
52?????}
53?
54?????fail("title?'"?+?title?+?"'?not?found");
55???}
56?
57???protected?final?Date?parseDate(String?s)?throws?ParseException?{
58???????return?new?SimpleDateFormat("yyyy-MM-dd").parse(s);
59???}
60?}
? I.搜索一個(gè)特定的Term 和利用QueryParser 解析用戶輸入的表達(dá)式
? 要利用一個(gè)特定的term搜索,使用QueryTerm就可以了,單個(gè)term 尤其適合Keyword搜索. 解析用戶輸入的表達(dá)式可以更適合用戶的使用方式,搜索表達(dá)式的解析有QueryParser來完成.如果表達(dá)式解析錯(cuò)誤 會(huì)有異常拋出, 可以取得相信的錯(cuò)誤信息 以便給用戶適當(dāng)?shù)奶崾?在解析表達(dá)式時(shí),還需要一個(gè)Analyzer 來分析用戶的輸入, 并根據(jù)不同的Analyzer來生產(chǎn)相應(yīng)的Term然后構(gòu)成Query實(shí)例.
下面看個(gè)例子吧:BasicSearchingTest.java
01?package?lia.searching;
02?
03?import?lia.common.LiaTestCase;
04?import?org.apache.lucene.analysis.SimpleAnalyzer;
05?import?org.apache.lucene.document.Document;
06?import?org.apache.lucene.index.Term;
07?import?org.apache.lucene.queryParser.QueryParser;
08?import?org.apache.lucene.search.Hits;
09?import?org.apache.lucene.search.IndexSearcher;
10?import?org.apache.lucene.search.Query;
11?import?org.apache.lucene.search.TermQuery;
12?
13?public?class?BasicSearchingTest?extends?LiaTestCase?{
14?
15???public?void?testTerm()?throws?Exception?{
16?????IndexSearcher?searcher?=?new?IndexSearcher(directory);
17?????Term?t?=?new?Term("subject",?"ant");??????????????? // 構(gòu)造一個(gè)Term
18?????Query?query?=?new?TermQuery(t);
19?????Hits?hits?=?searcher.search(query);???????????????? // 搜索
20?????assertEquals("JDwA",?1,?hits.length());???????????? //測試結(jié)果
21?
22?????t?=?new?Term("subject",?"junit");
23?????hits?=?searcher.search(new?TermQuery(t));??????????????????
24?????assertEquals(2,?hits.length());
25?
26?????searcher.close();
27???}
28?
29???public?void?testKeyword()?throws?Exception?{? // 測試關(guān)鍵字搜索
30?????IndexSearcher?searcher?=?new?IndexSearcher(directory);
31?????Term?t?=?new?Term("isbn",?"1930110995");???????????????? // 關(guān)鍵字 term
32?????Query?query?=?new?TermQuery(t);
33?????Hits?hits?=?searcher.search(query);
34?????assertEquals("JUnit?in?Action",?1,?hits.length());
35???}
36?
37???public?void?testQueryParser()?throws?Exception?{? // 測試 QueryParser.
38?????IndexSearcher?searcher?=?new?IndexSearcher(directory);
39?
40?????Query?query?=?QueryParser.parse("+JUNIT?+ANT?-MOCK",
41?????????????????????????????????????"contents",
42?????????????????????????????????????new?SimpleAnalyzer());? // 通過解析搜索表達(dá)式 返回一個(gè)Query實(shí)例
43?????Hits?hits?=?searcher.search(query);
44?????assertEquals(1,?hits.length());
45?????Document?d?=?hits.doc(0);
46?????assertEquals("Java?Development?with?Ant",?d.get("title"));
47?
48?????query?=?QueryParser.parse("mock?OR?junit",
49???????????????????????????????"contents",
50???????????????????????????????new?SimpleAnalyzer());?????????????
// 通過解析搜索表達(dá)式 返回一個(gè)Query實(shí)例
51?????hits?=?searcher.search(query);
52?????assertEquals("JDwA?and?JIA",?2,?hits.length());
53???}
54?}