读书人

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

发布时间: 2012-12-27 10:17:10 作者: rapoo

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

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也是可以用的代码不需改变

读书人网 >编程

热点推荐