热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

搜索为将IKAnalyzerlucene6.6适配

前言在中文分词器中,IKAnalyzer做的是相对不错的,有着细度分割和智能使用两个模式。但是,这个版本因为太陈旧,作者不再维护,(项目估计是。。。),所以与现在的Lucene6.

前言

在中文分词器中, IKAnalyzer 做的是相对不错的,有着细度分割和智能使用两个模式 。
但是,这个版本因为太陈旧,作者不再维护,(项目估计是。。。),所以与现在的Lucene 6.6 版本差距有些大。所以,我就根据网上各位大神的文章,加上自己对 API 与源码的阅读,稍微的进行了改动,可以简单的运行。
注: 这里的简单是指,可以简单的运行源码 中的简单案例。

正文

项目介绍

  1. IKAnaylzer版本: IK Analyzer 2012FF

感谢提供的分词源码 http://git.oschina.net/wltea/…

  1. lucene 版本:lucene 6.60

代码改动

1.对IKTokenizer的改动

源码

/**
* Lucene 4.0 Tokenizer适配器类构造函数
* @param in
* @param useSmart
*/
public IKTokenizer(Reader in, boolean useSmart) {
super(in);
offsetAtt = addAttribute(OffsetAttribute.class);
termAtt = addAttribute(CharTermAttribute.class);
typeAtt = addAttribute(TypeAttribute.class);
_IKImplement = new IKSegmenter(input, useSmart);
}

经查阅 lucene 源码
Tokenizer类的构造器已经不再接收 Reader 源码如下

protected Tokenizer() {
this.input = ILLEGAL_STATE_READER;
this.inputPending = ILLEGAL_STATE_READER;
}
protected Tokenizer(AttributeFactory factory) {
super(factory);
this.input = ILLEGAL_STATE_READER;
this.inputPending = ILLEGAL_STATE_READER;
}

因此改动 IKTokenizer 类 ,如下

public IKTokenizer( boolean useSmart) {
super();
offsetAtt = addAttribute(OffsetAttribute.class);
termAtt = addAttribute(CharTermAttribute.class);
typeAtt = addAttribute(TypeAttribute.class);
//传入 IKSegmenter 的 input Reader 流,会被 父类 Tokenizer 类的无参构造器
//初始化为 this.input = ILLEGAL_STATE_READER;
_IKImplement = new IKSegmenter(input, useSmart);
}

去除了 Reader 形参 。 默认调用 父类 的 无参构造函数 Tokenizer()
注:在该博客下发现,还需要配置分词器工厂类,因此还要多增加一段构造器代码,如下

//方便创建 工厂类
public IKTokenizer(AttributeFactory factory, boolean useSmart) {
super(factory);
offsetAtt = addAttribute(OffsetAttribute.class);
termAtt = addAttribute(CharTermAttribute.class);
typeAtt = addAttribute(TypeAttribute.class);
_IKImplement = new IKSegmenter(input, useSmart);
}

2. 对IKAnalyzer 的改动

源码

/**
* 重载Analyzer接口,构造分词组件
*/
@Override
protected TokenStreamComponents createComponents(String fieldName, final Reader in) {
Tokenizer _IKTokenizer = new IKTokenizer(in, this.useSmart());
return new TokenStreamComponents(_IKTokenizer);
}

lucene 6.6 关于 Analyzer 接口中 关于 createComponents() 方法的源码

protected abstract Analyzer.TokenStreamComponents createComponents(String var1);

结合上文中对 IKTokenizer 源码的改动,因此需要去除 参数 Reader in
改动的代码 如下:

/**
* 重载Analyzer接口,构造分词组件
*/
@Override
protected TokenStreamComponents createComponents(String fieldName) {
Tokenizer _IKTokenizer = new IKTokenizer(this.useSmart());
return new Analyzer.TokenStreamComponents(_IKTokenizer);
}

3. 对SWMCQueryBuilder 的改动

源码如下:

// 借助lucene queryparser 生成SWMC Query
QueryParser qp = new QueryParser(Version.LUCENE_43, fieldName, new StandardAnalyzer(
Version.LUCENE_43));
qp.setDefaultOperator(QueryParser.AND_OPERATOR);
qp.setAutoGeneratePhraseQueries(true);

由于新版本的 lucene 已经不在使用 Version 类 进行定义,(我的上一篇lucene6.6 学习心得说的很清楚)因此需要将之移除。
移除后,改动版本如下:

//借助lucene queryparser 生成SWMC Query
QueryParser qp = new QueryParser(fieldName, new StandardAnalyzer());
qp.setDefaultOperator(QueryParser.AND_OPERATOR);
qp.setAutoGeneratePhraseQueries(true);

4. 对IKQueryExpressionParser 的改动

IKQueryExpressionParser 类中方法 BooleanQuery ,在近期的 lucene 中有了较大改动,不知道的话,可以 查阅我的上一篇文章lucene6.6 学习心得.
因此源码中对 IKQueryExpressionParser 类中关于 BooleanQuery 的方法都需要进行更改。
因为方法中代码过多 , 因此,我选取其中比较关键的几个地方,进行展示。
关键源码如下:

private Query toBooleanQuery(Element op) {
BooleanQuery resultQuery = new BooleanQuery();
Query q2 = this.querys.pop();
Query q1 = this.querys.pop();
BooleanClause[] clauses = ((BooleanQuery) q1).getClauses();
resultQuery.add(c);
return resultQuery;
}

改动代码如下:
1.数组版本

private Query toBooleanQuery(Element op){
BooleanQuery.Builder builder = new BooleanQuery.Builder();
Query q2 = this.querys.pop();
Query q1 = this.querys.pop();
//因为,我看源码,并没有发现会增删的地方 ,于是直接转成了数组
//迭代器版本的在下文
if(q1 instanceof BooleanQuery){
BooleanClause[] clauses =(BooleanClause[]) ((BooleanQuery)q1).clauses().toArray();
if(clauses.length > 0
&& clauses[0].getOccur() == Occur.MUST){
for(BooleanClause c : clauses){
builder.add(c);
}
}else{
builder.add(q1,Occur.MUST);
}
return builder.build();
}

2.迭代器版本

private Query toBooleanQuery(Element op){
BooleanQuery.Builder builder = new BooleanQuery.Builder();
Query q2 = this.querys.pop();
Query q1 = this.querys.pop();
if(q1 instanceof BooleanQuery){
Iterator clauses = ((BooleanQuery) q1).iterator();
while (clauses.hasNext()) {
BooleanClause clause = clauses.next();
if (clause.getOccur() == Occur.MUST) {
builder.add(clause);
} else {
builder.add(q1,Occur.MUST);
}
}
return builder.build();
}

5. 项目运行

打开包中的测试代码
1.IKAnalzyerDemo
运行结果如下图

《搜索为将 -- IKAnalyzer -- lucene6.6适配》
2.LuceneIndexAndSearchDemo
运行结果如下图

《搜索为将 -- IKAnalyzer -- lucene6.6适配》

5. 源码与整合包的下载

源码与整合包 已经上传至我的 GitHub 上,有兴趣的可以去那里下载,不嫌弃的话,Star 一下 ,也是可以的哦~


推荐阅读
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 微软头条实习生分享深度学习自学指南
    本文介绍了一位微软头条实习生自学深度学习的经验分享,包括学习资源推荐、重要基础知识的学习要点等。作者强调了学好Python和数学基础的重要性,并提供了一些建议。 ... [详细]
  • EPICS Archiver Appliance存储waveform记录的尝试及资源需求分析
    本文介绍了EPICS Archiver Appliance存储waveform记录的尝试过程,并分析了其所需的资源容量。通过解决错误提示和调整内存大小,成功存储了波形数据。然后,讨论了储存环逐束团信号的意义,以及通过记录多圈的束团信号进行参数分析的可能性。波形数据的存储需求巨大,每天需要近250G,一年需要90T。然而,储存环逐束团信号具有重要意义,可以揭示出每个束团的纵向振荡频率和模式。 ... [详细]
  • 云原生边缘计算之KubeEdge简介及功能特点
    本文介绍了云原生边缘计算中的KubeEdge系统,该系统是一个开源系统,用于将容器化应用程序编排功能扩展到Edge的主机。它基于Kubernetes构建,并为网络应用程序提供基础架构支持。同时,KubeEdge具有离线模式、基于Kubernetes的节点、群集、应用程序和设备管理、资源优化等特点。此外,KubeEdge还支持跨平台工作,在私有、公共和混合云中都可以运行。同时,KubeEdge还提供数据管理和数据分析管道引擎的支持。最后,本文还介绍了KubeEdge系统生成证书的方法。 ... [详细]
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
  • baresip android编译、运行教程1语音通话
    本文介绍了如何在安卓平台上编译和运行baresip android,包括下载相关的sdk和ndk,修改ndk路径和输出目录,以及创建一个c++的安卓工程并将目录考到cpp下。详细步骤可参考给出的链接和文档。 ... [详细]
  • FeatureRequestIsyourfeaturerequestrelatedtoaproblem?Please ... [详细]
  • 本文介绍了Android 7的学习笔记总结,包括最新的移动架构视频、大厂安卓面试真题和项目实战源码讲义。同时还分享了开源的完整内容,并提醒读者在使用FileProvider适配时要注意不同模块的AndroidManfiest.xml中配置的xml文件名必须不同,否则会出现问题。 ... [详细]
  • C++字符字符串处理及字符集编码方案
    本文介绍了C++中字符字符串处理的问题,并详细解释了字符集编码方案,包括UNICODE、Windows apps采用的UTF-16编码、ASCII、SBCS和DBCS编码方案。同时说明了ANSI C标准和Windows中的字符/字符串数据类型实现。文章还提到了在编译时需要定义UNICODE宏以支持unicode编码,否则将使用windows code page编译。最后,给出了相关的头文件和数据类型定义。 ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • 解决nginx启动报错epoll_wait() reported that client prematurely closed connection的方法
    本文介绍了解决nginx启动报错epoll_wait() reported that client prematurely closed connection的方法,包括检查location配置是否正确、pass_proxy是否需要加“/”等。同时,还介绍了修改nginx的error.log日志级别为debug,以便查看详细日志信息。 ... [详细]
  • mac php错误日志配置方法及错误级别修改
    本文介绍了在mac环境下配置php错误日志的方法,包括修改php.ini文件和httpd.conf文件的操作步骤。同时还介绍了如何修改错误级别,以及相应的错误级别参考链接。 ... [详细]
  • iOS超签签名服务器搭建及其优劣势
    本文介绍了搭建iOS超签签名服务器的原因和优势,包括不掉签、用户可以直接安装不需要信任、体验好等。同时也提到了超签的劣势,即一个证书只能安装100个,成本较高。文章还详细介绍了超签的实现原理,包括用户请求服务器安装mobileconfig文件、服务器调用苹果接口添加udid等步骤。最后,还提到了生成mobileconfig文件和导出AppleWorldwideDeveloperRelationsCertificationAuthority证书的方法。 ... [详细]
author-avatar
支持骸云
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有