lucene在时间范围内对关键字的查询和分页

一般简单的全文检索只需要输入关键字,然后我们按时间倒序对结果排序。
当数据量庞大的时候还是不够友好,所以需要加上时间范围的约束。
本文是基于别人的例子改的,只为个人积累^_^
[color=red]参考出处[/color][url]http://zfsn.iteye.com/blog/520363[/url]


public class SearchUtil {

//索引所在文件夹
private String indexDir;
//查询起始时间
private String sDateStr;
//查询结束时间
private String eDateStr;
private RangeQuery rangeQuery;
private Query query;
private BooleanQuery booleanQuery;
//时间格式化类型
private static SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");

public Map getSearchResult(String searchType, String key, Date sDate,
Date eDate, int start, int limit) {

booleanQuery = new BooleanQuery();
// 搜索开始时间
Date beginTime = new Date();
ArrayList al = new ArrayList();
HashMap map = new HashMap();
// 获取记录数组
List list = new ArrayList();
Analyzer analyzer = new IKAnalyzer();
Searcher searcher = null;
Directory directory = null;
try{
// 定义解析器
QueryParser parser = new QueryParser(searchType, analyzer);
indexDir = IndexUtil.getValue(IndexUtil.INDEX_ROOT2);
//indexDir 为了测试可以直接写成绝对路径
directory = FSDirectory.open(new File(indexDir));
searcher = new IndexSearcher(directory);
searcher.setSimilarity(new IKSimilarity());

// 若只有结束值起始值默认为1900年1月1日
if ((sDate == null || "".equals(sDate))
&& (eDate != null && !"".equals(eDate))) {
Calendar calendar = Calendar.getInstance();
calendar.set(1900, 0, 1);
sDate = calendar.getTime();
}
// 若只有起始值结束值默认为当天
if ((sDate != null && !"".equals(sDate))
&& (eDate == null || "".equals(eDate))) {
eDate = new Date();
}
if ((sDate != null && !"".equals(sDate))
&& (eDate != null || !"".equals(eDate))) {

// Lucene日期转换格式不准,改用format格式
// sDateStr=DateTools.dateToString(sDate,
// DateTools.Resolution.MINUTE);
// eDateStr=DateTools.dateToString(eDate,
// DateTools.Resolution.MINUTE);

sDateStr = sdf.format(sDate);
eDateStr = sdf.format(eDate);

//时间范围查询
Term tstart = new Term("createDate", sDateStr);
Term tend = new Term("createDate", eDateStr);
rangeQuery = new RangeQuery(tstart, tend, true);
}

if (key != null && !"".equals(key)) {
query = parser.parse(key);
}

//按条件进行多条件查询
if ((sDate != null && !"".equals(sDate))
&& (eDate != null && !"".equals(eDate)) && (key != null)
&& !"".equals(key)) {
booleanQuery.add(rangeQuery, BooleanClause.Occur.MUST);
booleanQuery.add(query, BooleanClause.Occur.MUST);
} else if ((sDate != null && !"".equals(sDate))
&& (eDate != null && !"".equals(eDate))) {
booleanQuery.add(rangeQuery, BooleanClause.Occur.MUST);

} else if (key != null && !"".equals(key)) {
booleanQuery.add(query, BooleanClause.Occur.MUST);

} else {
booleanQuery.add(rangeQuery, BooleanClause.Occur.SHOULD);
booleanQuery.add(query, BooleanClause.Occur.SHOULD);
}

// 索引排序条件
SortField[] sortfield = new SortField[] { SortField.FIELD_SCORE,
new SortField("createDate", SortField.STRING, true) };
Sort sort = new Sort(sortfield);
TopFieldDocs docs = searcher.search(booleanQuery, null, 1, sort);
int totalNum = docs.totalHits;
docs = searcher.search(booleanQuery, null, totalNum, sort);
ScoreDoc[] scoreDocs = docs.scoreDocs;

//高亮设置
SimpleHTMLFormatter simpleHtmlFormatter = new SimpleHTMLFormatter(
"<FONT COLOR='RED'>", "</FONT>");
Highlighter highlighter = new Highlighter(simpleHtmlFormatter,
new QueryScorer(query));
// 设置提取字符串长度
highlighter.setTextFragmenter(new SimpleFragmenter(58));

if (scoreDocs.length == 0) {
System.out.println("没有符合条件的记录");
} else {

for (int i = start; i < scoreDocs.length && i < start + limit; i++) {

ScoreDoc scdoc = scoreDocs[i];
Document document = searcher.doc(scdoc.doc);

TokenStream tokenStream = analyzer.tokenStream("",
new StringReader(document.get("content")));
//提取高亮显示内容
String str = highlighter.getBestFragment(tokenStream, document
.get("content"));
System.out.println(str);
System.out.println(document.getField("createDate").toString());
al.add(str);
}

// 搜索完成时间
Date endTime = new Date();
// 搜索所耗时间
long timeOfSearch = endTime.getTime() - beginTime.getTime();
System.out.println("The time For indexsearch is " + timeOfSearch
+ " ms");

map.put("list", al);
map.put("time", timeOfSearch);
map.put("total", totalNum);
}
}catch (Exception e) {
e.printStackTrace();

}finally {
if (searcher != null) {
try {
searcher.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (directory != null) {
try {
directory.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return map;
}

//测试方法
public static void main(String[] args) {
SearchUtil s = new SearchUtil();
try {
Date sDate = sdf.parse("20101228");
Date eDate = sdf.parse("20101229");
s.getSearchResult("content", "星期三", null, eDate, 0, 15);
} catch (Exception e) {
e.printStackTrace();
}
}
}


ps: lucene版本为2.9.3 不过3.0也是可以用的代码不需改变
  • 0
    点赞
  • 0
    收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
评论

打赏作者

zn85600301

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值