`

搜索技术--搜索、排序并高亮显示(lucene3.0)

阅读更多
搜索思路:

1 用一个indexSearcher对象,去一个预先建立的索引文件(indexFir)中查找关键字(key).

2其中要先对关键字采用特定的分词器(analyzer)进行解析(解析器(parser)),解析后作为query对象,再去查。

3.遍历结果集,根据docId去doc集合中找相应的doc.

4.设置高亮显示的格式,每条匹配记录显示的字符数。用highlighter对象,取得文章或数据的片段并将与关键字相同的文章,标红。

关于如何建立索引,请查看:搜索技术--建立索引(lucene3.0)

package com.jrj.datamart.action;

import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.cn.smart.SmartChineseAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Fieldable;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.highlight.Highlighter;
import org.apache.lucene.search.highlight.QueryScorer;
import org.apache.lucene.search.highlight.SimpleFragmenter;
import org.apache.lucene.search.highlight.SimpleHTMLFormatter;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
import com.jrj.datamart.model.ApiIndexEntity;
import com.jrj.datamart.model.Pagination;

//
//搜索并返回结果
public class SearcherAction extends BaseAction{

// 保存索引的地方
private String INDEX_DIR = "f:\\lucene\\luceneIndexDir";
private String keyword = "行情";
private int TOP_NUM = 100;
private int numIndexed;
// 保持搜索结果的List
List<ApiIndexEntity> apiIndexEntityLists = new ArrayList<ApiIndexEntity>();
// 搜索结果的个数
private int totalHitsNumber;
// 用时(毫秒)
private long spentTime;
  //struts2中的主方法
public String execute() throws Exception {
  System.out.println("execue of SearcherAction started...keyword: "
    + keyword);
  long start = new Date().getTime();

  File indexDir = new File(INDEX_DIR);
  if (!indexDir.exists() || !indexDir.isDirectory()) {
   throw new Exception(indexDir
     + " does not exist or is not a directory.");
  }
  search(indexDir, keyword);
  long end = new Date().getTime();
  spentTime = (end - start);
  System.out.println("searing spent: " + spentTime + " milliseconds");

  return "success";
}
//查詢
// @param indexDir
//           索引目录地址
// @param q
//            要查询的字符串
// @throws Exception
//
public void search(File indexDir, String q) throws Exception {
  SmartChineseAnalyzer analyzer = new SmartChineseAnalyzer(
    Version.LUCENE_30);

  String field = "contents";
  try {
   // 排序
   IndexSearcher indexSearch = new IndexSearcher(
     FSDirectory.open(indexDir));
   QueryParser parser = new QueryParser(Version.LUCENE_30, field,
     analyzer);
   // AND--->OR
   parser.setDefaultOperator(QueryParser.OR_OPERATOR);
   // 生成Query对象
   // 多域查询
   // String[] fields = { "icnname", "contents" };
   // BooleanClause.Occur[] flags = { BooleanClause.Occur.SHOULD,
   // BooleanClause.Occur.SHOULD };
   // MultiFieldQueryParser.parse(Version.LUCENE_30, q, fields, flags,
   // analyzer);
   // TopScoreDocCollector topCollector = TopScoreDocCollector.create(
   // indexSearch.maxDoc(), false);
   Query query = parser.parse(q);
   // 排序: 先API中文名,后描述
   // SortField sortArray[];
   // SortField sortField1 = new SortField("icnname", SortField.STRING,
   // false);// false代表升序,TRUE代表降序
   // SortField sortField2 = new SortField("contents",
   // SortField.STRING,
   // false);// false代表升序,TRUE代表降序
   // sortArray = new SortField[] { sortField1, sortField2 };
   // Sort sort = new Sort(sortArray);
   // TopDocs topDocs = indexSearch.search(query, null, 1000, sort);
   // indexSearch.search(query, topCollector);
   TopDocs topDocs = indexSearch.search(query, TOP_NUM);
   totalHitsNumber = topDocs.totalHits;
   System.out.println("命中:" + totalHitsNumber);
   // 输出结果
   ScoreDoc[] scoreDocs = topDocs.scoreDocs;
   ApiIndexEntity apiIndexEntity;
   // 将符合结果的都保持到list中。/
   // 设置需要高亮的字段值
   String[] highlightCol = { "icnname", "contents" };
   Highlighter highlighter = null;
   // 关键字高亮显示设置
   // 设定高亮显示的格式,也就是对高亮显示的词组加上前缀后缀
   SimpleHTMLFormatter simpleHTMLFormatter = new SimpleHTMLFormatter(
     "<FONT COLOR='#FF0000'>", "</FONT>");
   highlighter = new Highlighter(simpleHTMLFormatter, new QueryScorer(
     query));
   // 设置每次返回的字符数
   highlighter.setTextFragmenter(new SimpleFragmenter(150));
   for (int i = 0; i < topDocs.totalHits; i++) {
    apiIndexEntity = new ApiIndexEntity();
    Document targetDoc = indexSearch.doc(scoreDocs[i].doc);
    for (Fieldable fa : targetDoc.getFields()) {
     String value = targetDoc.get(fa.name());
     for (String col : highlightCol) {
      if (fa.name().equals(col)) {
       // 设置高显内容
       TokenStream tokenStream = analyzer.tokenStream(
         "content", new StringReader(value));
       value = highlighter.getBestFragment(tokenStream,
         value);
       if ("icnname".equals(fa.name())) {
          apiIndexEntity.setIcnname(value == null ? targetDoc.get("icnname") : value);
       } else if ("contents".equals(fa.name())) {
        apiIndexEntity.setContents(value == null ? targetDoc.get("contents") : value);
       }
      }
     }  

}
    apiIndexEntity.setApiid(Integer.parseInt(targetDoc.get("apiid")));
    System.out.println("ApiId: "
      + targetDoc.get("apiid").toString());
    System.out.println("API中文名: "
      + targetDoc.get("icnname").toString());
    System.out
      .println("内容:" + targetDoc.get("contents").toString());
    apiIndexEntityLists.add(apiIndexEntity);

   }
   //将数据放入session中,
   getSession().setAttribute("apiIndexEntityLists",apiIndexEntityLists);

   //设置session时间1小时。
   getSession().setMaxInactiveInterval(60*60);
  

  } catch (CorruptIndexException e) {

   e.printStackTrace();
  } catch (IOException e) {

   e.printStackTrace();
  }
}

public int getNumIndexed() {
  return numIndexed;
}

public void setNumIndexed(int numIndexed) {
  this.numIndexed = numIndexed;
}

public String getINDEX_DIR() {
  return INDEX_DIR;
}

public String getKeyword() {
  return keyword;
}

public int getTOP_NUM() {
  return TOP_NUM;
}

public void setINDEX_DIR(String iNDEX_DIR) {
  INDEX_DIR = iNDEX_DIR;
}

public void setKeyword(String keyword) {
  this.keyword = keyword;
}

public void setTOP_NUM(int tOP_NUM) {
  TOP_NUM = tOP_NUM;
}

public List<ApiIndexEntity> getApiIndexEntityLists() {
  return apiIndexEntityLists;
}

public void setApiIndexEntityLists(List<ApiIndexEntity> apiIndexEntityLists) {
  this.apiIndexEntityLists = apiIndexEntityLists;
}

public int getTotalHitsNumber() {
  return totalHitsNumber;
}

public void setTotalHitsNumber(int totalHitsNumber) {
  this.totalHitsNumber = totalHitsNumber;
}

public long getSpentTime() {
  return spentTime;
}

public void setSpentTime(int spentTime) {
  this.spentTime = spentTime;
}

}
分享到:
评论

相关推荐

    lucene3.0-api.CHM

    4. 高亮显示:使用Highlighter类可以高亮显示搜索匹配的部分。 四、高级特性 1. 分块索引(Segment):Lucene以分块的形式存储索引,支持大数量的文档和高效的数据管理。 2. 基于内存的搜索:使用RAMDirectory...

    java lucene3.0 jar包

    Java Lucene 3.0的使用涉及到多个步骤,包括设置分析器(Analyzer)来处理不同语言的文本,创建索引(IndexWriter),查询索引(Searcher),以及对搜索结果进行评分和排序。同时,开发者还需要关注性能优化,例如...

    Lucene3.0_pdf

    通过《Lucene3.0原理与代码分析》的学习,读者可以掌握如何利用Lucene构建自己的全文搜索引擎,理解其高效检索背后的算法和技术,并能根据实际需求定制和优化索引和查询流程。尽管本文档基于3.0版本,但Lucene的基本...

    Lucene3.0做的文件搜索

    除了搜索,Lucene还提供了一些其他功能,如文档的增删改查、多字段搜索、排序、分页、高亮显示搜索结果等。此外,它还可以与其他Apache项目如Solr和Elasticsearch集成,以构建更复杂的搜索引擎解决方案。 总之,...

    基于lucene3.0的搜索器源程序

    5. 结果展示:处理搜索结果,包括排序、分页和高亮显示匹配的关键词。 三、部署到Tomcat等服务器 为了在Web环境中使用Lucene搜索器,我们需要将其部署到像Tomcat这样的Servlet容器中。首先,确保服务器环境中已经...

    Lucene 3.0 原理与代码分析完整版

    - **过滤器与高亮**:使用Filter可以对搜索结果进行进一步筛选,高亮工具可以突出显示匹配的搜索词。 **6. Lucene 3.0 版本特性** Lucene 3.0版本引入了一些重要的改进和新特性,包括: - 提升了性能和稳定性,...

    Apache Lucene3.0 入门实例介绍

    - **Highlighting**:高亮显示搜索结果中的匹配部分。 - ** Spell Checking**:提供拼写纠错功能。 - **Multi-field search**:在一个文档中支持多字段搜索。 - **Update Index**:在线更新索引,无需重建整个...

    Lucene in Action 2nd

    - **高级特性探索**:深入探讨 Lucene 的一些高级特性,如高亮显示、近似匹配等。 #### 知识点四:Lucene 内部原理与定制化 除了基本的使用指南之外,《Lucene in Action》还深入剖析了 Lucene 的内部工作原理,为...

    Lucene3.5源码jar包

    5. **内存缓存与过滤器**:Lucene提供`Filter`类来处理如文档过滤、高亮显示等功能。同时,`BitSet`类用于在内存中高效地存储和操作文档集。 6. **倒排索引的优化**:在`MergePolicy`和`MergeScheduler`中,你可以...

    全文搜索lucene知识

    - **高亮显示**(Highlighting):在搜索结果中突出显示匹配的关键词。 - **分面搜索**(Faceted Search):提供分类和过滤功能,增强用户导航体验。 ### 6. 代码分析 在Lucene 3.0的代码中,你可以看到如何使用...

    Lucene.Net_2_9_1 含高亮等包完整版

    使用高亮器,我们可以突出显示搜索查询中的关键字,使其在文档内容中更加醒目。通常,这涉及到将原始文本分词,找到匹配的搜索词,然后用特定的格式(如不同的颜色或样式)替换这些关键词。在Lucene.Net 2.9.1中,这...

    lucene 资料全集

    3. **高亮显示**: 可以突出显示搜索结果中的匹配词。 4. **近实时搜索**: 通过NRT(Near Real Time)机制,能在短时间内反映出索引的最新变化。 5. **复杂查询构造**: 提供高级查询构造器,如SpanQuery,支持精确...

    lucene in action 书中例子源码

    `Highlighter`类则用于高亮显示搜索结果中的关键词。 7. **分布式搜索**:虽然3.0版本的Lucene不直接支持分布式搜索,但书中可能包含如何在单机环境下模拟多节点索引和查询的方法,这对于理解后来的Solr或Elastic...

    up_441903_SolrPhpClient_baqvxr.rar

    在实际应用中,你可能需要根据业务需求对查询进行更复杂的配置,例如使用过滤器查询(filter queries)、高亮显示、分组、排序等。 对于提供的文件列表,`fileinfo.txt`可能包含关于文件元数据的信息,而其他`.txt`...

Global site tag (gtag.js) - Google Analytics