Lucene基础(三)-- 中文分词及高亮显示
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基础(三)-- 中文分词及高亮显示的更多相关文章
- 【Lucene】Apache Lucene全文检索引擎架构之中文分词和高亮显示4
前面总结的都是使用Lucene的标准分词器,这是针对英文的,但是中文的话就不顶用了,因为中文的语汇与英文是不同的,所以一般我们开发的时候,有中文的话肯定要使用中文分词了,这一篇博文主要介绍一下如何使用 ...
- lucene之中文分词及其高亮显示(五)
中文分词:即换个分词器 Analyzer analyzer = new StandardAnalyzer();// 标准分词器 换成 SmartChineseAnalyzer analyze ...
- 用于Lucene的各中文分词比较
对几种中文分析器,从分词准确性和效率两方面进行比较.分析器依次为:StandardAnalyzer.ChineseAnalyzer.CJKAnalyzer.IK_CAnalyzer.MIK_CAnal ...
- Lucene学习——IKAnalyzer中文分词
一.环境 1.平台:MyEclipse8.5/JDK1.5 2.开源框架:Lucene3.6.1/IKAnalyzer2012 3.目的:测试IKAnalyzer的分词效果 二.开发调试 1.下载框架 ...
- lucene之中文分词及其高亮显示
参考:http://www.cnblogs.com/lirenzhujiu/p/5914174.html http://www.cnblogs.com/xing901022/p/3933675.htm ...
- (转)全文检索技术学习(三)——Lucene支持中文分词
http://blog.csdn.net/yerenyuan_pku/article/details/72591778 分析器(Analyzer)的执行过程 如下图是语汇单元的生成过程: 从一个Re ...
- Lucene系列四:Lucene提供的分词器、IKAnalyze中文分词器集成、扩展 IKAnalyzer的停用词和新词
一.Lucene提供的分词器StandardAnalyzer和SmartChineseAnalyzer 1.新建一个测试Lucene提供的分词器的maven项目LuceneAnalyzer 2. 在p ...
- Lucene 03 - 什么是分词器 + 使用IK中文分词器
目录 1 分词器概述 1.1 分词器简介 1.2 分词器的使用 1.3 中文分词器 1.3.1 中文分词器简介 1.3.2 Lucene提供的中文分词器 1.3.3 第三方中文分词器 2 IK分词器的 ...
- JAVAEE——Lucene基础:什么是全文检索、Lucene实现全文检索的流程、配置开发环境、索引库创建与管理
1. 学习计划 第一天:Lucene的基础知识 1.案例分析:什么是全文检索,如何实现全文检索 2.Lucene实现全文检索的流程 a) 创建索引 b) 查询索引 3.配置开发环境 4.创建索引库 5 ...
随机推荐
- mysql中的第三范式
※多表操作 (凡是多表,都要用到关联技术(把多表合并成一个新表): 左关联.右关联.内关联.还有一个外(全)关联,MySQL不支持,为考虑软件兼容,我们开发一般不用.) ※表与表之间的关系:1对1,1 ...
- TableView不显示没内容的Cell怎么办?
类似这种,我不想让下面那些空的显示. 很简单: self.tableView.tableFooterView = [[UIView alloc] init]; 加完这句之后就变成了这样:
- linux__升级java版本
java下载地址:http://www.oracle.com/index.html 使用which java查看到,Java的环境变量指向的还是/usr/bin/java,问题找到了.于是就进行了下面 ...
- matlab中num2str的应用
在求导数,积分,方程的过程中,难免会遇到一些参数要随着情况有点变化,这时,你就需要能够动态的表示出你的表达式,Num2str函数是一个相当有用的函数,一般配合[]连接符使用,下面将我接触到的一些用法写 ...
- MATLAB的循环结构
循环结构有两种基本形式:while 循环和for 循环.两者之间的最大不同在于代码的重复是如何控制的.在while 循环中,代码的重复的次数是不能确定的,只要满足用户定义的条件,重复就进行下去.相对地 ...
- [原]Unity3d中奇怪的编译错误
整理项目,重新build时出现一些问题,这些代码在原项目中都是可以运行的. 错误信息如下: Assets/XXXXX.cs(79,35): error CS0103: The name `NNNNNN ...
- Xamarin 安装体验
1.先从官网下载https://www.xamarin.com/downloadXamarin for Visual Studio 2.MAC上下载https://store.xamarin.com/ ...
- eclipse怎么切换SVN的用户
在用eclipse的时候会经常用到SVN来进行代码的版本控制,为了方便起见,我们会保存密码,从此之后就不会再出现输入或者修改用户名和密码的地方了,这时候想切换用户怎么办,在本地操作的一种方法是删除SV ...
- oracle学习(1)
1.安装完oracle数据库后,远程第一次无法登陆,需要进入sys用户后,更改以此后才有效. 2.TNS去读取配置的时候,如果在环境变量中已经配置了 TNS_ADMIN 后,则直接从此目录下读取. 3 ...
- Java中的String类
/*String类用于描述字符串事物的那么它就提供了多个方法对字符串进行操作 方法都会用,字符串这块就结束了常见的操作有哪些?“abcd”它应该具备什么功能,我们才能更好得操作它?1.获取(必须要掌握 ...