public class SearchUtil {
//索引所在文件夹
private String indexDir;
private String sDateStr;
private String eDateStr;
private RangeQuery rangeQuery;
private Query query;
private BooleanQuery booleanQuery,booleanQuery2;
private DateFormat format = new SimpleDateFormat("yyyyMMdd");
private Logger logger=Logger.getLogger(this.getClass());
public List<Information> getSearchResult(String searchWhich,Set<Type> types,String key,Date sDate, Date eDate,int start,int limit) throws Exception{
booleanQuery = new BooleanQuery();
booleanQuery2=new BooleanQuery();
Iterator<Type> it=types.iterator();
while(it.hasNext()){
Term t=new Term("informationTypeId",it.next().getId()+"");
Query typeQuery=new TermQuery(t);
booleanQuery2.add(typeQuery, BooleanClause.Occur.SHOULD);
}
//获取记录数组
List<Information> list=new ArrayList<Information>();
Analyzer analyzer=new IKAnalyzer();
//定义解析器
QueryParser parser=new QueryParser(searchWhich,analyzer);
//读入索引文件
IndexReader reader=IndexReader.open(indexDir);
//定义查询器
Searcher searcher=new IndexSearcher(reader);
//定义查询结果集,最多显示200条结果记录
// TopDocCollector topCollector=new TopDocCollector(200);
//若只有结束值起始值默认为1900年1月1日
if((sDate==null || "".equals(sDate))&&(eDate!=null && !"".equals(eDate))){
Calendar calendar= Calendar.getInstance();
calendar.set(1900, 1,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=format.format(sDate);
eDateStr=format.format(eDate);
Term tstart=new Term("informationCreateDate",sDateStr);
Term tend=new Term("informationCreateDate",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(booleanQuery2,BooleanClause.Occur.MUST);
booleanQuery.add(rangeQuery, BooleanClause.Occur.MUST);
booleanQuery.add(query,BooleanClause.Occur.MUST);
}else if((sDate!=null && !"".equals(sDate))&&(eDate!=null && !"".equals(eDate))){
booleanQuery.add(booleanQuery2,BooleanClause.Occur.MUST);
booleanQuery.add(rangeQuery, BooleanClause.Occur.MUST);
}else if(key!=null && !"".equals(key)){
booleanQuery.add(booleanQuery2,BooleanClause.Occur.MUST);
booleanQuery.add(query,BooleanClause.Occur.MUST);
}else{
booleanQuery.add(booleanQuery2,BooleanClause.Occur.MUST);
booleanQuery.add(rangeQuery, BooleanClause.Occur.SHOULD);
booleanQuery.add(query,BooleanClause.Occur.SHOULD);
}
Sort sort = new Sort(new SortField("informationCreateDate",SortField.STRING,true));
TopFieldDocs docs=searcher.search(booleanQuery, null, 200, sort);
//执行查询操作
// searcher.search(booleanQuery, topCollector);
//返回附带评分机制的结果集数组
ScoreDoc[] scoreDocs=docs.scoreDocs;
if(scoreDocs.length==0){
System.out.println("没有符合条件的记录");
}else{
for(int i=start;i<scoreDocs.length&&i<start+limit;i++){
//找到这个document原来的索引值
int docId=scoreDocs[i].doc;
//根据这个值找到对象的document
Document doc=searcher.doc(docId);
Information info = new Information();
String title = doc.get("informationTitle");
String content = doc.get("informationContent");
String source = doc.get("informationSource");
String url = doc.get("informationUrl");
String id = doc.get("informationId");
String date = doc.get("informationCreateDate");
// 高亮
SimpleHTMLFormatter sHtmlF = new SimpleHTMLFormatter("<span style='background-color:yellow'>", "</span>");
Highlighter highlighter=null;
String titleFragment=null;
String contentFragment=null;
if(query!=null){
highlighter = new Highlighter(sHtmlF, new QueryScorer(query));
// 设置高亮附近的字数
highlighter.setTextFragmenter(new SimpleFragmenter(200));
// 标题
titleFragment = highlighter.getBestFragment(analyzer,"title", title);
contentFragment= highlighter.getBestFragment(analyzer, searchWhich, content);
}
if(titleFragment != null && !titleFragment.trim().equals("")) {
info.setTitle(titleFragment);
}else{
info.setTitle(title);
}
if(contentFragment!=null&&!contentFragment.trim().equals("")){
info.setContent(contentFragment);
}else{
info.setContent(content);
}
info.setSource(source);
info.setUrl(url);
info.setCreateDate(DateUtil.getDate(date, "yyyyMMdd"));
info.setId(new Integer(id));
list.add(info);
}
}//else
logger.debug("search:" + list.size());
return list;
}
}
分享到:
相关推荐
- **RangeQuery**:用于指定一个范围内的查询,如年龄、日期等,可以设置是否包含边界。可以使用TermRangeQuery类创建或通过QueryParser解析包含边界符号的字符串。 - **BooleanQuery**:用于组合多个查询条件,...
总结,Lucene的查询语法是其强大功能的核心,理解和掌握这些概念及技巧,能够帮助我们构建更高效、精准的搜索系统。在实际应用中,结合具体场景进行优化,将使Lucene发挥出更大的价值。在探索更多示例和实践过程中,...
- **排序**:通过调整查询参数,可以基于文档的相关度、发布日期或其他自定义字段对结果进行排序。 - **分页**:为了提高用户体验,搜索引擎通常会限制每次返回的结果数量,实现分页展示,如每页10条记录。 - **...
这些特性使得Lucene可以处理复杂的查询场景,比如根据用户评分、发布日期等因素调整搜索结果的排序。 在实际应用中,我们还需要考虑性能优化。例如,通过使用Filter进行范围查询,可以减少不必要的文档扫描;或者...
这使得用户能够按类别聚合文档,例如,根据作者、日期或其他分类标准来查看搜索结果。 在 Lucene 中,分组功能并不是内建的,但可以通过自定义 collector 来实现。`GroupCollector` 就是这样一个关键组件,它是实现...
Lucene支持多种查询语法,如布尔查询、短语查询、模糊查询等,允许用户进行复杂的组合查询。同时,它还提供了一个高级查询API,可以构建更复杂的查询模式。 搜索执行阶段,Lucene会根据解析后的查询在索引中查找...
- **多条件查询**:`BooleanQuery`组合多个查询条件。 - **短语查询**:`PhraseQuery`查找文档中包含特定顺序词汇的短语。 - **模糊查询**:`FuzzyQuery`允许搜索近似匹配的词。 #### 3.3 QueryParser - 自动生成`...
- **查询解析**: 用户输入的查询字符串会被解析成查询对象,可以是简单的关键词查询,也可以是复杂的布尔组合查询。 - **评分与排序**: Lucene基于TF-IDF算法对匹配结果进行评分,高分的文档在搜索结果中优先展示...
- **排序与评分**:分析了Lucene中如何根据相关性对搜索结果进行排序,并介绍了不同评分策略的影响。 - **章节6:扩展搜索功能** - **自定义搜索器**:指导读者如何根据实际需求编写自定义搜索器,以增强搜索能力...
- **Query**: Lucene 支持多种查询类型,如 TermQuery(匹配单个词项)、BooleanQuery(组合多个查询)、PhraseQuery(匹配短语)等。查询对象表示了用户想要查找的信息模式。 - **Scoring**: Lucene 使用 TF-IDF...
Lucene支持在一个文档中对多个字段进行独立或组合的搜索。可以指定在哪些字段上进行查询,并可以设置每个字段的权重,以影响最终的评分。 8. **倒排索引** Lucene的核心数据结构是倒排索引,它允许快速定位包含...
- 布尔查询(BooleanQuery):组合多个查询条件,如AND、OR、NOT。 - 范围查询(RangeQuery):查找在指定范围内的结果。 - 通配符查询(WildcardQuery):支持星号(*)和问号(?)作为通配符。 执行搜索后,Lucene...
Lucene的核心特性包括文档索引、文本分析、查询解析与执行以及结果排序。它的设计理念是将非结构化的文本数据转化为结构化的索引,从而能够快速地进行全文检索。让我们逐一解析这些关键部分: 1. **文档索引**:...
- **复杂查询构造**:除了基本查询外,还可以使用布尔操作符组合多个查询,创建复杂的查询表达式。 - **过滤器与筛选**:Filter类用于限制搜索结果,如按日期、地理位置等条件筛选。 7. **优化与维护** Lucene提供...
用户可以通过这些查询类型组合出复杂的搜索条件。 7. **Hit 和 Score**:搜索结果以 Hit 形式返回,每个 Hit 包含匹配文档的相关信息和得分。得分是根据查询和文档之间的相关性计算得出,用于排序结果。 8. **...
5. **搜索(Search)**:用户输入查询后,Lucene会将查询语句转换为词项的组合,然后在索引中查找匹配的文档。 6. **评分(Scoring)**:Lucene会根据查询与文档的相关性给出一个评分,用于排序搜索结果。 7. **...
- **搜索**: Lucene支持快速的全文本搜索,包括基本的关键词搜索、布尔组合查询、短语查询和模糊查询。 - **排序与评分**: 除了返回匹配的文档,Lucene还能根据相关性对结果进行排序。 - **多语言支持**: Lucene...
1. **布尔查询(Boolean Queries)**:支持 AND、OR、NOT 等逻辑操作符,组合多个查询条件。 2. **短语查询(Phrase Queries)**:查找特定顺序的多个术语,如 "大数据技术"。 3. **模糊查询(Fuzzy Queries)**:...
总结,Lucene和IKAnalyzer的组合为我们提供了构建中文全文搜索引擎的强大工具。通过理解它们的工作原理和核心组件,我们可以灵活地应用于各种项目中,提升数据检索的效率和用户体验。在实际开发中,还需要考虑性能...
1. **多字段搜索(Multi-field Search)**: 可以同时在多个字段上进行搜索,使用布尔运算符(AND, OR, NOT)来组合查询。 2. **短语搜索(Phrase Search)**: 支持精确的短语匹配,如搜索“大数据技术”。 3. **...