Lucene分词器及高亮

分词器

在lucene中我们按照分词方式把文档进行索引,不同的分词器索引的效果不太一样,之前的例子使用的都是标准分词器,对于英文的效果很好,但是中文分词效果就不怎么样,他会按照汉字的字直接分词,没有词语的概念。

使用分词的地方只需要把Analyzer实例化成我们第三方的分词器即可

中文分词有很多,这里使用IKAnalyzer 为例, 
下载地址 https://git.oschina.net/wltea/IK-Analyzer-2012FF 现在下来后里面有一篇教程。

高亮

导入lucene-highlighter-xxx.jar 在对查询出来的结果实现高亮显示

// 关键字高亮显示的html标签,需要导入lucene-highlighter-xxx.jar

  SimpleHTMLFormatter simpleHTMLFormatter = new SimpleHTMLFormatter("<span style='color:red'>", "</span>");

  Highlighter highlighter = new Highlighter(simpleHTMLFormatter, new QueryScorer(query));

  for (int i = 0; i < hits.length; i++) {

    Document doc = isearcher.doc(hits[i].doc);

    // 内容增加高亮显示

    TokenStream tokenStream = analyzer.tokenStream("content", new StringReader(doc.get("content")));

    String content = highlighter.getBestFragment(tokenStream, doc.get("content")); System.out.println(content);

  }

Lucene中文分词器

package lucene_demo04;

import java.io.IOException;
import java.io.StringReader;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.IndexWriterConfig.OpenMode;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.QueryWrapperFilter;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.highlight.Highlighter;
import org.apache.lucene.search.highlight.InvalidTokenOffsetsException;
import org.apache.lucene.search.highlight.QueryScorer;
import org.apache.lucene.search.highlight.SimpleHTMLFormatter;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.RAMDirectory;
import org.apache.lucene.util.Version;
import org.wltea.analyzer.lucene.IKAnalyzer;

/**
* 中文分词,IKAnalayzer,对索引结果实现高亮显示
*
* @author YipFun
*/
public class LuceneDemo04
{
  private static final Version version = Version.LUCENE_4_9;
  private Directory directory = null;
  private DirectoryReader ireader = null;
  private IndexWriter iwriter = null;
  private IKAnalyzer analyzer;

  // 测试数据
  private String[] content = { "你好,我是中共人", "中华人民共和国", "中国人民从此站起来了", "Lucene是一个不错的全文检索的工具", "全文检索中文分词" };

  /**
   * 构造方法
   */
  public LuceneDemo04()
  {
    directory = new RAMDirectory();
  }

  private IKAnalyzer getAnalyzer()
  {
    if (analyzer == null)
    {
      return new IKAnalyzer();
    } else
    {
      return analyzer;
    }
  }

  /**
  * 创建索引
  */
  public void createIndex()
  {
    Document doc = null;
    try
    {
      IndexWriterConfig iwConfig = new IndexWriterConfig(version, getAnalyzer());
      iwConfig.setOpenMode(OpenMode.CREATE_OR_APPEND);
      iwriter = new IndexWriter(directory, iwConfig);
      for (String text : content)
      {
      doc = new Document();
      doc.add(new TextField("content", text, Field.Store.YES));
      iwriter.addDocument(doc);
    }

  } catch (IOException e)
  {
    e.printStackTrace();
  } finally
  {
  try
  {
    if (iwriter != null)
    iwriter.close();
  } catch (IOException e)
  {
    e.printStackTrace();
  }
  }

  }

  public IndexSearcher getSearcher()
  {
    try
    {
      if (ireader == null)
      {
        ireader = DirectoryReader.open(directory);
      } else
      {
        DirectoryReader tr = DirectoryReader.openIfChanged(ireader);
        if (tr != null)
        {
          ireader.close();
          ireader = tr;
        }
      }
      return new IndexSearcher(ireader);
    } catch (CorruptIndexException e)
    {
      e.printStackTrace();
    } catch (IOException e)
    {
      e.printStackTrace();
    }
    return null;
  }

  public void searchByTerm(String field, String keyword, int num) throws InvalidTokenOffsetsException
  {
    IndexSearcher isearcher = getSearcher();
    Analyzer analyzer = getAnalyzer();
    // 使用QueryParser查询分析器构造Query对象
    QueryParser qp = new QueryParser(version, field, analyzer);
    // 这句所起效果?
    qp.setDefaultOperator(QueryParser.OR_OPERATOR);
    try
    {
      Query query = qp.parse(keyword);
      ScoreDoc[] hits;

      // 注意searcher的几个方法
      hits = isearcher.search(query, null, num).scoreDocs;

      // 关键字高亮显示的html标签,需要导入lucene-highlighter-xxx.jar
      SimpleHTMLFormatter simpleHTMLFormatter = new SimpleHTMLFormatter("<span style='color:red'>", "</span>");
      Highlighter highlighter = new Highlighter(simpleHTMLFormatter, new QueryScorer(query));

      for (int i = 0; i < hits.length; i++)
      {
        Document doc = isearcher.doc(hits[i].doc);
        // 内容增加高亮显示
        TokenStream tokenStream = analyzer.tokenStream("content", new StringReader(doc.get("content")));
        String content = highlighter.getBestFragment(tokenStream, doc.get("content"));
        System.out.println(content);
      }

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

  /**
  * 使用过滤器查询
  *
  * @param field
  * @param keyword
  * @param num
  * @throws InvalidTokenOffsetsException
  */
  public void searchByTermFilter(String field, String keyword, int num) throws InvalidTokenOffsetsException
  {
    IndexSearcher isearcher = getSearcher();
    Analyzer analyzer = getAnalyzer();
    // 使用QueryParser查询分析器构造Query对象
    QueryParser qp = new QueryParser(version, field, analyzer);
    // 这句所起效果?
    qp.setDefaultOperator(QueryParser.OR_OPERATOR);
    try
    {
      Query query = qp.parse(keyword);
      Query q2 = qp.parse("全文检索");
      ScoreDoc[] hits;

      QueryWrapperFilter filter = new QueryWrapperFilter(q2);
      // 注意searcher的几个方法
      hits = isearcher.search(query, filter, num).scoreDocs;

      // 关键字高亮显示的html标签,需要导入lucene-highlighter-xxx.jar
      SimpleHTMLFormatter simpleHTMLFormatter = new SimpleHTMLFormatter("<span style='color:red'>", "</span>");
      Highlighter highlighter = new Highlighter(simpleHTMLFormatter, new QueryScorer(query));

      for (int i = 0; i < hits.length; i++)
      {
        Document doc = isearcher.doc(hits[i].doc);
        // 内容增加高亮显示
        TokenStream tokenStream = analyzer.tokenStream("content", new StringReader(doc.get("content")));
        String content = highlighter.getBestFragment(tokenStream, doc.get("content"));
        System.out.println(content);
      }

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

  public static void main(String[] args) throws InvalidTokenOffsetsException
  {
    System.out.println("start");
    LuceneDemo04 ld = new LuceneDemo04();
    ld.createIndex();
    long start = System.currentTimeMillis();
    ld.searchByTerm("content", "人民", 500);
    System.out.println("end search use " + (System.currentTimeMillis() - start) + "ms");
  }

}

运行结果:

start 加载扩展词典:ext.dic

加载扩展停止词典:stopword.dic

中华<span style='color:red'>人民</span>共和国

中国<span style='color:red'>人民</span>从此站起来了

end search use 129ms

Lucene基础(三)-- 中文分词及高亮显示的更多相关文章

  1. 【Lucene】Apache Lucene全文检索引擎架构之中文分词和高亮显示4

    前面总结的都是使用Lucene的标准分词器,这是针对英文的,但是中文的话就不顶用了,因为中文的语汇与英文是不同的,所以一般我们开发的时候,有中文的话肯定要使用中文分词了,这一篇博文主要介绍一下如何使用 ...

  2. lucene之中文分词及其高亮显示(五)

    中文分词:即换个分词器 Analyzer analyzer = new StandardAnalyzer();// 标准分词器     换成  SmartChineseAnalyzer analyze ...

  3. 用于Lucene的各中文分词比较

    对几种中文分析器,从分词准确性和效率两方面进行比较.分析器依次为:StandardAnalyzer.ChineseAnalyzer.CJKAnalyzer.IK_CAnalyzer.MIK_CAnal ...

  4. Lucene学习——IKAnalyzer中文分词

    一.环境 1.平台:MyEclipse8.5/JDK1.5 2.开源框架:Lucene3.6.1/IKAnalyzer2012 3.目的:测试IKAnalyzer的分词效果 二.开发调试 1.下载框架 ...

  5. lucene之中文分词及其高亮显示

    参考:http://www.cnblogs.com/lirenzhujiu/p/5914174.html http://www.cnblogs.com/xing901022/p/3933675.htm ...

  6. (转)全文检索技术学习(三)——Lucene支持中文分词

    http://blog.csdn.net/yerenyuan_pku/article/details/72591778 分析器(Analyzer)的执行过程 如下图是语汇单元的生成过程:  从一个Re ...

  7. Lucene系列四:Lucene提供的分词器、IKAnalyze中文分词器集成、扩展 IKAnalyzer的停用词和新词

    一.Lucene提供的分词器StandardAnalyzer和SmartChineseAnalyzer 1.新建一个测试Lucene提供的分词器的maven项目LuceneAnalyzer 2. 在p ...

  8. Lucene 03 - 什么是分词器 + 使用IK中文分词器

    目录 1 分词器概述 1.1 分词器简介 1.2 分词器的使用 1.3 中文分词器 1.3.1 中文分词器简介 1.3.2 Lucene提供的中文分词器 1.3.3 第三方中文分词器 2 IK分词器的 ...

  9. JAVAEE——Lucene基础:什么是全文检索、Lucene实现全文检索的流程、配置开发环境、索引库创建与管理

    1. 学习计划 第一天:Lucene的基础知识 1.案例分析:什么是全文检索,如何实现全文检索 2.Lucene实现全文检索的流程 a) 创建索引 b) 查询索引 3.配置开发环境 4.创建索引库 5 ...

随机推荐

  1. (转载)c语言指针学习

    前言 近期俄罗斯的陨石.四月的血月.五月北京的飞雪以及天朝各种血腥和混乱,给人一种不详的预感.佛祖说的末法时期,五浊恶世 ,十恶之世,人再无心法约束,道德沦丧,和现在正好吻合.尤其是在天朝,空气,水, ...

  2. 打造强大的BaseModel(1):让Model自我描述

    前言 从事iOS开发已经两年了,从一无所知到现在能独立带领团队完成一系列APP的开发,网络上的大神给了我太多的帮助.他们无私地贡献自己的心得和经验,写出了一篇篇精美的文章.现在我也开始为大家贡献自己的 ...

  3. Android(java)学习笔记154:使用GridView以及重写BaseAdapter

    1.BaseAdapter: 对于ListView.GridView.Gallery.Spinner等等,它是它们的适配器,直接继承自接口类Adapter的,使用BaseAdapter时需要重写很多方 ...

  4. uiautomator日志文件转换为xml格式文件

    如果想把uiautomator的日志文件,转换成漂亮的xml文件,那么可以使用automator-log-converter.jar工具, 工具使用方法: 使用工具automator-log-conv ...

  5. Tinymce4 中Ajax多次加载时,会出现菜单在第二次进入时,显示的下拉菜单在左上角

    在项目中,ajax多次导入tinymce的js包 参考了: Having issues with Multiple AJAX refresh and TinyMCE load page with ti ...

  6. WEB前端优化一些经验技巧

    引言: 1. 慢的页面可能会网站失去更多的用户. 2. 慢500ms意味着20%的用户将放弃访问(google) 3. 慢100ms意味着1%的用户将放弃交易(amazon) 前段时间偶然看到网上的两 ...

  7. ASP获取当前页面带参数的网址(URL地址)的方法

    '获取当前Url参数的函数 Function GetUrl() Dim ScriptAddress,Servername,qs ScriptAddress = CStr(Request.ServerV ...

  8. SQL SERVER 主键约束

    主键约束: 遵循关系型模型中的第二范式.唯一的识别一条记录,不能为空. CREATE TABLE Persons ( Id_P int NOT NULL PRIMARY KEY, LastName v ...

  9. powerdesigner 使用的几点问题

    一.powerdesigner 没有DataBase?: powerdesigner 只有在选择物理模型PDM的时候才会出现数据库菜单. 二.PowerDesigner版本控制功能? 1.首先介绍一下 ...

  10. WCF编程系列(七)信道及信道工厂

    WCF编程系列(七)信道及信道工厂   信道及信道栈 前面已经提及过,WCF中客户端与服务端的交互都是通过消息来进行的.消息从客户端传送到服务端会经过多个处理动作,在WCF编程模型中,这些动作是按层 ...