【Lucene4.8教程之三】搜索

释放双眼,带上耳机,听听看~!

1、关键类

Lucene的搜索过程中涉及的主要类有以下几个:

(1)IndexSearcher:执行search()方法的类

(2)IndexReader:对索引文件进行读操作,并为IndexSearcher提供搜索接口

(3)Query及其子类:查询对象,search()方法的重要参数

(4)QueryParser:根据用户输入的搜索词汇生成Query对象。

(5)TopDocs:search()方法返回的前n个文档

(6)ScoreDocs:提供TopDocs中搜索结果的访问接口

2、搜索的关键步骤

(1)创建IndexReader

(2)使用IndexReader创建IndexSearcher

(3)根据搜索关键字,使用QueryParser生成Query对象

(4)以Query作为参数调用IndexSearcher.search(),执行搜索

(5)以TopDocs以及ScoreDocs遍历结果并处理

示例代码如下:

[java]  view plain copy

//(1)创建IndexReader
  
1.
Directory indexDir2 = FSDirectory.open(indexDir);  
1.
IndexReader ir = DirectoryReader.open(indexDir2);  
1.
//(2)使用IndexReader创建IndexSearcher
  
1.
IndexSearcher searcher = 
new
 IndexSearcher(ir);  
1.
//(3)根据搜索关键字,使用QueryParser生成Query对象
  
1.
QueryParser parser = 
new
 QueryParser(Version.LUCENE_48, 
"contents"
,
new
 SimpleAnalyzer(Version.LUCENE_48));  
1.
Query query = 
null
;  
1.
try
 {  
1.
    query = parser.parse(term);  
1.
    } 
catch
 (ParseException e) {  
1.
        e.printStackTrace();  
1.
    }  
1.
//(4)以Query作为参数调用IndexSearcher.search(),执行搜索
  
1.
TopDocs docs = searcher.search(query, 
30
);        
1.
  
1.
//(5)以TopDocs以及ScoreDocs遍历结果并处理
  
1.
ScoreDoc[] hits = docs.scoreDocs;  
1.
System.out.println(hits.length);  
1.
for
 (ScoreDoc hit : hits) {  
1.
            System.out.println(
"doc: "
 + hit.doc + 
" score: "
 + hit.score);  
1.
        }  

3、关于IndexReader

(1)IndexReader未提供构造函数,因此需要通过DirectoryReader.open()方法来创建一个IndexReader。

(2)创建一个IndexReader需要较大的系统开销,因此最好在所有搜索期间都重复使用一个IndexReader,只有在必要的时候才建议打开新的IndexReader。

(3)在创建IndexReader时,它会搜索已有的索引快照,如果你需要搜索索引中的变更信息,那么必须打开一个新的reader。所幸的是IndexReader.reopen方法是一个获取新IndexReader的有效方法,能在耗费较少系统资源的情况下使用当前reader来获取索引中所有的变更信息。【新版本中已废弃,待确认替代方法】

4、关于QueryParser与Query的子类

对于一个搜索而言,其核心语句为:

[java]  view plain copy

searcher.search(query, 
10
);  

此时,其最重要的参数为一个Qeury对象。构造一个Query对象有2种方法:【均以在contents域搜索java关键词为例】

(1)使用Query的子类,如BooleanQuery, ConstantScoreQuery, DisjunctionMaxQuery, FilteredQuery, MatchAllDocsQuery, MultiPhraseQuery, MultiTermQuery, PhraseQuery, SpanQuery, TermQuery,直接实例化一个对外:

[java]  view plain copy

searcher.search( 
new
 TermQuery(
new
 Term(
"contents"
,
"java"
)), 
10
);  

以下语句结构更为清晰

[java]  view plain copy

Term term= 
new
 Term(
"contents"
,
"java"
);  
1.
TermQuery tq = 
new
 TermQuery(term);  
1.
searcher.search(tq , 
10
);  

此外,即为在contents域中搜索包括java的文档。

(2)使用QueryParser的parse()方法,对所传入的搜索关键词汇进行解释,并返回query对象。

[java]  view plain copy

QueryParser parser = 
new
 QueryParser(Version.LUCENE_48, 
"contents"
,
new
 SimpleAnalyzer(Version.LUCENE_48));  
1.
Query query = 
null
;  
1.
try
 {  
1.
    query = parser.parse(
"java"
);  
1.

catch
 (ParseException e) {  
1.
    e.printStackTrace();  
1.
}  
1.
TopDocs docs = searcher.search(query, 
10
);  

以上语句创建一个QueryParser,其默认搜索域为contents,然后将搜索词汇转化为Query对象。

如果指定QueryParser的默认搜索域为全部?如何指定一个Query的搜索域?

关于QueryParser与Query子类的更详细内容,请参见

【Lucene4.8教程之六】QueryParser与Query子类:如何生成Query对象 http://blog.csdn.net/jediael_lu/article/details/33288793

给TA打赏
共{{data.count}}人
人已打赏
安全运维

OpenSSH-8.7p1离线升级修复安全漏洞

2021-10-23 10:13:25

安全运维

设计模式的设计原则

2021-12-12 17:36:11

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索