使用lucene开发简单的站内搜索
关于这个内容javaeye已经有不错的例子了
http://jnotnull.javaeye.com/blog/275327
在这个例子的基础上我想说一一些需要注意的地方。
1.重建索引和增量索引:
IndexWriter writer
=
new
IndexWriter(directory,analyzer,rebuild,
new
IndexWriter.MaxFieldLength(
200000
));
只需要在构造IndexWriter的时候设置rebuild值就可以了
当rebuild设为true的时候:就会删除原来的索引,重建索引文件
当rebuild设为false时:表示增量索引,是在原来索引文件的基础上增加新的索引内容,当然第一次没有索引文件的时候必须先重建索引生成索引文件。
在lucene2.4中不使用 Field.Index.TOKENIZED而是使用 Field.Index.ANALYZED,表示要对这个field进行分词
if
(article.getArticleId()
!=
null
)
doc.add( new Field(Fields.FIELD_ARTICLEID,article.getArticleId(),Field.Store.YES,Field.Index.NOT_ANALYZED));
if (article.getTitle() != null )
doc.add( new Field(Fields.FIELD_TITLE,article.getTitle(),Field.Store.YES,Field.Index.ANALYZED));
当然这里的
Fields.FIELD_ARTICLEID是自定义的类变量
doc.add( new Field(Fields.FIELD_ARTICLEID,article.getArticleId(),Field.Store.YES,Field.Index.NOT_ANALYZED));
if (article.getTitle() != null )
doc.add( new Field(Fields.FIELD_TITLE,article.getTitle(),Field.Store.YES,Field.Index.ANALYZED));
2.分页检索
ScoreDoc[] hits
=
searcher.search(query,
null
,startIndex
+
perPage,
new
Sort(
new
SortField(Fields.FIELD_CHECKTIME,SortField.AUTO,
true
))).scoreDocs;
int numTotalHits = searcher.maxDoc(); // hits.length;
int endIndex = Math.min(numTotalHits,startIndex + perPage);
使用
searcher.maxDoc()取出搜索的总记录数,使用
search(query,
null
,startIndex
+
perPage,
new
Sort(
new
SortField(Fields.FIELD_CHECKTIME,SortField.AUTO,
true
))).scoreDocs取出当前一页的索引记录(这个是2.4的新用法,可以获得更高的性能),
new
Sort(
new
SortField(Fields.FIELD_CHECKTIME,SortField.AUTO,
true
)))来处理索引结果的排序。int numTotalHits = searcher.maxDoc(); // hits.length;
int endIndex = Math.min(numTotalHits,startIndex + perPage);
Document doc
=
searcher.doc(hits[i].doc);
String title1 = doc.get(Fields.FIELD_TITLE);
使用
searcher.doc(hits[i].doc)取出索引的具体记录
String title1 = doc.get(Fields.FIELD_TITLE);
3.高亮显示
SimpleHTMLFormatter simpleHTMLFormatter
=
new
SimpleHTMLFormatter(
"
<b><font color='red'>
"
,
"
</font></b>
"
);
Highlighter highlighter = new Highlighter(simpleHTMLFormatter,
new QueryScorer(query));
highlighter.setTextFragmenter( new SimpleFragmenter(bestMatchSize));
if (title1 != null ) {
TokenStream tokenStream = analyzer.tokenStream(Fields.FIELD_TITLE,
new StringReader(title1));
highLightTitle = highlighter.getBestFragment(tokenStream,title1);
}
new
SimpleHTMLFormatter(
"
<b><font color='red'>
"
,
"
</font></b>
"
)构造高亮显示的样式。
Highlighter highlighter = new Highlighter(simpleHTMLFormatter,
new QueryScorer(query));
highlighter.setTextFragmenter( new SimpleFragmenter(bestMatchSize));
if (title1 != null ) {
TokenStream tokenStream = analyzer.tokenStream(Fields.FIELD_TITLE,
new StringReader(title1));
highLightTitle = highlighter.getBestFragment(tokenStream,title1);
}
highlighter.setTextFragmenter( new SimpleFragmenter(bestMatchSize))设置显示索引内容的最大字符数,相当于自动抽取含有关键的摘要。
当然这个只是简单索引和检索过程。
还有一些其他工作要做:
1.索引的过程就是查询的过程,需要把没有索引的文章查询出来进行索引,完毕有要打上标记。这里面就要为文章扩展索引标记,建立一些文章查询。
2.将索引操作加入调度定时执行,这个用quartz就可以了。