Lucene高亮显示

前面一节我们基本了解了Lucene的一些基本使用,索引的创建,搜索。

接下去让我们的搜索结果高亮!

需要的架包(版本比较低~)

  <dependencies>
    <!-- https://mvnrepository.com/artifact/org.apache.lucene/lucene-core -->
	<dependency>
	    <groupId>org.apache.lucene</groupId>
	    <artifactId>lucene-core</artifactId>
	    <version>2.3.0</version>
	</dependency>
	
	<!-- https://mvnrepository.com/artifact/org.apache.lucene/lucene-highlighter -->
	<dependency>
	    <groupId>org.apache.lucene</groupId>
	    <artifactId>lucene-highlighter</artifactId>
	    <version>2.3.0</version>
	</dependency>
  </dependencies>
我们现在项目根目录下的analyzer/files/目录下创建两个txt文件,内容分别为:

我是中国人, I am Chinese!
你好, Hello World

windows用户用记事本的话注意保存成utf-8的格式。

准备工作完成了,接下去创建索引,代码:

/**
 * 创建索引
 * @author TangXW
 *
 */
public class IndexHandler{
	public void doIndex() throws Exception{
		File fileDir = new File("analyzer/files/");  // 需要索引的位置
		File indexDir = new File("analyzer/");  // 索引存放位置
		
		Analyzer strandardAnalyzer = new StandardAnalyzer();  // 分析器
		// true表示如果原来已经有索引文件,则覆盖
		IndexWriter indexWriter = new IndexWriter(indexDir, strandardAnalyzer, true);
		
		File[] textFiles = fileDir.listFiles();
		if(textFiles != null && textFiles.length > 0){
			for(int i = 0; i < textFiles.length; i++){
				// 如果是txt文件
				if(textFiles[i].isFile() && textFiles[i].getName().endsWith(".txt")){
					String temp = FileReaderAll(textFiles[i].getCanonicalPath(), "UTF-8");
					Document document = new Document();
					// 建立一个body索引,即txt的内容,并且存储索引
					Field fieldBody = new Field("body", temp, Field.Store.YES, Field.Index.TOKENIZED);
					document.add(fieldBody);
					// 入库
					indexWriter.addDocument(document);
				}
			}
		}
		indexWriter.optimize(); // 整合优化
		indexWriter.close();
	}
	
	
	/**
	 * 获取文件中的全部内容
	 * @param fileName
	 * @param charset
	 * @return
	 * @throws IOException
	 */
	public static String FileReaderAll(String fileName, String charset) throws IOException{
        BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(fileName), charset));
        String line = new String();
        StringBuffer temp = new StringBuffer();

        while((line = reader.readLine()) != null){
            temp.append(line);
        }
        reader.close();
        return temp.toString();
    }
}

   和前面的文章基本一样,注意的是body这个所以一定要存储,即Field.Store.YES,因为你要高亮显示,所以这些信息肯定是要存储的,不然的话等下检索的时候会报错。

  编写检索的接口:

public class SearchHandler {
	public void doSearch(String sql) throws Exception{
		// TODO Auto-generated method stub
		IndexSearcher searcher = new IndexSearcher("analyzer/");
		
		Analyzer analyzer = new StandardAnalyzer();
		QueryParser qp = new QueryParser("body", analyzer);
		Query query = qp.parse(sql);
		if(searcher != null){
			
			// 设置高亮显示
			SimpleHTMLFormatter simpleHTMLFormatter = new SimpleHTMLFormatter("<span style='color:red'>", "</span>");
			Highlighter highlighter = new Highlighter(simpleHTMLFormatter, new QueryScorer(query));
			
			Hits hits = searcher.search(query);
			if(searcher != null){
				System.out.println("hits.length = " + hits.length());
				for(int i = 0; i < hits.length(); i++){
					Document doc = hits.doc(i);
					
					/**
					 * 高亮显示
					 * 这里要注意analyzer.tokenStream()中的body也就是先前我们加的索引
					 * 一定是要存储的,即【Field.Store.YES】,因为你要显示肯定是要存储的
					 */
					TokenStream tokenStream = analyzer.tokenStream("body", new StringReader(doc.get("body")));
					String content = highlighter.getBestFragment(tokenStream, doc.get("body"));
					System.out.println(content);
					
				}
			}
		}
	}
}

以上接口全部完成,接下去我们test一下

public class Test {
	public static void main(String[] args) throws Exception{
		// 1. 创建索引
		IndexHandler indexHandler = new IndexHandler();
		indexHandler.doIndex();
		
		// 2. 搜索
		SearchHandler searchHandler = new SearchHandler();
		searchHandler.doSearch("chinese");
	}
}
发现工程目录下多了三个索引文件,这是lucene生成的


  运行结果:

hits.length = 1
我是中国人, I am <span style='color:red'>Chinese</span>!
ok,高亮显示了。因为我们这里用的是StandardAnalyzer的标准解析器,我们也可以用一些中文解析器,比如SmartChineseAnalyzer,这里就不细说了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值