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

Lucene/Solr开发经验

1、开篇语2、概述3、渊源4、初识Solr5、Solr的安装6、Solr分词顺序7、Solr中文应用的一个实例8、Solr的检索运算符[开篇语]按照惯例应该写一篇技术文章了,这次结合Lucene

1、开篇语
2、概述
3、渊源
4、初识Solr
5、Solr的安装
6、Solr分词顺序
7、Solr中文应用的一个实例
8、Solr的检索运算符

[开篇语]按照惯例应该写一篇技术文章了,这次结合Lucene/Solr来分享一下开发经验。

Lucene是一个使用Java语言写的全文检索开发包(API),利用它可以实现强大的检索功能,它的详细介绍大家可以去Google上搜索一下,本文重点放在Solr相关的讨论上。

[概述]目前国内研究Solr的人不多,而且大多是因为项目开发需要。Solr师承Lucene,为 Apache基金会下的一个项目,具体的说它还是Lucene下的一个子项目。Solr出身豪门,而且具有自己的技术特点,填补了以往Lucene仅仅作 为开发工具包的遗憾,它是一个完完整整地应用。换句话说,它是一个全文检索服务器,它开箱即用,让我们能立马体会到Lucene的强大功能,为 Lucene产品化走出了一大步。
Solr分词原理演示界面
Solr分词原理演示界面

[渊源]最初,CNET Networks使用Lucene API来开发了一些应用,并在这个基础上产生了Solr的雏形,后来Apache Software Foundation在Lucene顶级项目的支持下得到了Solr,这已经是2006年1月份的事了。2006年1月17日,Solr正是加入 Apache基金会的孵化项目,在整个项目孵化期间,Solr 稳步地积累各种特性并吸引了一个稳定的user群体、developer群体和Committer群体,并于1年之后的17日正式酝酿成熟,在这之前已经 成功发布了1.1.0版。目前的稳定版本是1.2,Solr在9月份的2007Apache年会上大放异彩,在今年11月底将来到香港参加2007亚洲开 源软件峰会,遗憾的是为什么不来北京:-(

[初识Solr]Solr服务器不同于普通的关系型数据库,不仅仅在于它核心本质的不同(面向结构化和非结构化 数据的不同),很大的不同还在于它的体系架构上。Solr服务器一般情况下需要部署于应用服务器/Java容器上(如果是本机通信不涉及RPC可以不使用 Java容器,如采用嵌入方式使用Solr),无法独立工作于JVM上。
Solr架构图
Solr架构图
Solr 服务器可以存储数据并通过索引对其进行快速高效检索。对外提供HTTP/XML和Json API接口,这使得它能够在多语言环境下集成,比如针对它的客户端的开发。Solr目前的客户端面向的有Java、PHP、Python、C#、Json 和Ruby等,遗憾的是没有面向C/C++(这也是本人目前在研究的),研究音乐搜索分类的Brian Whitman曾在苹果平台上使用JNI技术在C代码中嵌入Solr实现检索,不过是一个Cocoa工程。有了这些客户端,使用者能很方便地将Solr集 成到具体运用中。目前最完善的当属Java客户端Solrj,以及加入到Solr trunk,并将在1.3版本中正式发布。

如果不研究开发Solr,只是使用Solr,只需要关注Solr的以下几个方面:
1、Solr服务器的配置在solrconfig.xml中完成,包括对缓存,servlet的个性化配置等等,即系统全局的配置;
2、索引方法、索引域(字段)等等在schema.xml中完成,这个配置是针对Solr实例的;
3、索引数据文件默认放在Solr文档根目录下的data/index目录下,这个路径可以通过第1点配置,同时可以将这个目录下的文件进行复制粘贴,即可完成索引的复用;
4、 建立索引的时间相当长,我采用按词无字典索引方式对2G110万条中文记录进行索引,花了将近2个半小时的时间(当然这个时间和很多因素有关,有兴趣的话 大家可以留言和我讨论),相对而言,在linux下建索引时间要比windows下快很多,可以使用commit操作使新增索引生效,同时注意索引的优 化,索引优化也是很费资源和时间的,但是优化索引也是提高检索速度的重要方法,因此需要好好权衡这一点;
5、安装完后的Solr目录下有这么几个文件夹:bin文件夹里主要是用于建立镜像和完成远程同步的脚本;conf文件夹下主要是1、2点中提到的配置文件;admin文件夹下是的主要是提供web管理界面的文件;
6、目前Solr1.2不具备安全性设计,没有用户组及权限设置,在进行具体应用时需要注意安全,目前最有效的方法是通过应用服务器上的授权实现。
本文永久链接:http://www.jinsehupan.com/blog/?p=25

[Solr的安装]Solr发行版中已经有一个使用Jetty为servlet容器的小例子,可以使用这个例子来体验,那正在在自己想部署的平台和应用服务器上该怎么一个步骤呢?

要开始使用 Solr,需安装以下软件:
1、Java 1.5 或更高版本;
2、Ant 1.6.x 或更高版本(用于编译管理Solr工程,个人推荐,当然可以使用eclipse);
3、Web 浏览器,用来查看管理页面(官方建议使用Firefox,但实际没有发现和IE有什么差别);
4、servlet 容器,如Tomcat 5.5(不建议使用6版本)。本文以Tomcat 在 8080 端口上运行为例。如果运行的是其他 servlet 容器或在其他的端口上运行,则可能要修改代码中的URL才能访问示例应用程序和 Solr。

下面开始安装配置:

1、使用Ant编译工程或下载示例应用程序,将Solr WAR 文件复制到 servlet 容器的webapps目录中;
2、得到Solr文件夹,以备随后将其复制到当前目录,可以使用ant build得到,也可以在下载的压缩包中找到,以它为模板以备之后的修改;
3、可以通过以下三种方式之一设置 Solr 的主位置:
设置 java 系统属性 solr.solr.home (没错,就是 solr.solr.home,一般在嵌入式集成中用得多);
配 置 java:comp/env/solr/home 的一个 JNDI 查找指向 solr 目录,建立/tomcat55/conf/Catalina/localhost/solr.xml文件,注意这个xml文件名将是Solr实例名称,2 中的当前目录被指定为下面中的f:/solrhome,文件内容如下:

  1.   

在包含 solr 目录的目录中启动 servlet 容器(默认的 Solr 主目录是当前工作目录下的 solr);
4、最后一点就是 如果有CJK(中日韩文字)应用,出现乱码问题,采用如下方法解决(其实已经不算是solr配置问题,而是应用服务器配置问题),修改Tomcat的 conf/server.xml文件中对于端口(本文为8080)的连接器统一资源编码为UTF-8,因为Solr1.2内核支持UTF-8编码:

  1.  
  2.   
  3.      ...
  4.  

[Solr分词顺序]Solr建立索引和对关键词进行查询都得对字串进行分词,在向索引库中添加全文检索类型的索引的时候,Solr会首先用空格进行分词,然后把分词结果依次使用指定的过滤器进行过滤,最后剩下的结果才会加入到索引库中以备查询。分词的顺序如下:
索引
1:空格whitespaceTokenize
2:过滤词StopFilter
3:拆字WordDelimiterFilter
4:小写过滤LowerCaseFilter
5:英文相近词EnglishPorterFilter
6:去除重复词RemoveDuplicatesTokenFilter
查询
1:查询相近词
2:过滤词
3:拆字
4:小写过滤
5:英文相近词
6:去除重复词
以上是针对英文,中文的除了空格,其他都类似

[Solr中文应用的一个实例]
1、首先配置schema.xml,这个相当于数据表配置文件,它定义了加入索引的数据的数据类型的。1.2版本的schema.xml主要包括types、fields和其他的一些缺省设置。

A、首先需要在types结点内定义一个FieldType子结点,包括name,class,positionIncrementGap等等一些 参数,name就是这个FieldType的名称,class指向org.apache.solr.analysis包里面对应的class名称,用来定 义这个类型的行为。在FieldType定义的时候最重要的就是定义这个类型的数据在建立索引和进行查询的时候要使用的分析器analyzer,包括分词 和过滤。在例子中text这个FieldType在定义的时候,在index的analyzer中使用 solr.WhitespaceTokenizerFactory这个分词包,就是空格分词,然后使用 solr.StopFilterFactory,solr.WordDelimiterFilterFactory,solr.LowerCaseFilterFactory,solr.EnglishPorterFilterFactory,solr.RemoveDuplicatesTokenFilterFactory 这几个过滤器。在向索引库中添加text类型的索引的时候,Solr会首先用空格进行分词,然后把分词结果依次使用指定的过滤器进行过滤,最后剩下的结果 才会加入到索引库中以备查询。Solr的analysis包并没有带支持中文的包,在这里我们采用lucene里的语言包(在下载后的solr压缩包 内,lib目录下有一个lucene-analyzers-2.2.0.jar包,里面含有中文处理的cn和cjk类),有cn和cjk两个类可以支持中 文。我们采用cjk类,并在schema.xml中加入如下配置:

  1.       
  2.     

支持类型定义完成了。

B、接下来的工作就是在fields结点内定义具体的字段(类似数据库中的字段),就是filed,filed定义包括name,type(为之前 定义过的各种FieldType),indexed(是否被索引),stored(是否被储存),multiValued(是否有多个值)等等。例如定义 如下:

  1.   
  2.   
  3.   
  4.   
  5.   
  6.   
  7.   
  8.   

field的定义相当重要,有几个技巧需注意一下,对可能存在多值得字段尽量设置multiValued属性为true,避免建索引是抛出错误;如果不需要存储相应字段值,尽量将stored属性设为false。

C、建议建立了一个拷贝字段,将所有的全文字段复制到一个字段中,以便进行统一的检索:

并在拷贝字段结点处完成拷贝设置:

  1.   

D、除此之外,还可以定义动态字段,所谓动态字段就是不用指定具体的名称,只要定义字段名称的规则,例如定义一个 dynamicField,name为*_i,定义它的type为text,那么在使用这个字段的时候,任何以_i结尾的字段都被认为是符合这个定义的, 例如name_i,gender_i,school_i等。

2、配置solrconfig.xml,用来配置Solr的一些系统属性,比较重要的一个就是可以通过更改其中的dataDir属性来指定索引文件 的存放位置,对于有大数据量的情况下还要进行自动commit操作配置,以下设置为当内存索引量达到20W条时自动进行往磁盘写操作,以免堆溢出,这也是 解决单个入库xml文件最好不要超过30M的有效方法:

  1.     200000
  2.  

3、配置好这些后,需要重新启动Solr服务器使配置生效,然后向其中添加数据。

4、添加数据是通过向服务器的update Servlet POST xml格式的数据来实现的,xml结构是这样的add中间有很多个doc,每个doc中有很多个field。添加到索引库中的每条记录都必须指定唯一的数 字id来唯一标识这条索引。建立好xml文件(例如solr.xml)之后,在exampledocs目录下执行:java -jar post.jar solr.xml来添加索引数据。对于post的jar包,如果重新配置了应用服务器,如使用了comcat,端口改为8080,实例名称改为solrx 了需要重新生成相应的post.jar包进行操作。

另附ronghao实现中文分词的案例供大家参考:

对全文检索而言,中文分词非常的重要,这里采用了qieqie庖丁分词(非常不错:))。集成非常的容易,我下载的是2.0.4-alpha2版 本,其中它支持最多切分和按最大切分。创建自己的一个中文TokenizerFactory继承自solr的BaseTokenizerFactory。

**

* Created by IntelliJ IDEA.

* User: ronghao

* Date: 2007-11-3

* Time: 14:40:59

* 中文切词 对庖丁切词的封装

*/

public class ChineseTokenizerFactory extends BaseTokenizerFactory {

/**

* 最多切分 默认模式

*/

public static final String MOST_WORDS_MODE = “most-words”;

/**

* 按最大切分

*/

public static final String MAX_WORD_LENGTH_MODE = “max-word-length”;

private String mode = null;

public void setMode(String mode) {

if (mode==null||MOST_WORDS_MODE.equalsIgnoreCase(mode)

|| “default”.equalsIgnoreCase(mode)) {

this.mode=MOST_WORDS_MODE;

} else if (MAX_WORD_LENGTH_MODE.equalsIgnoreCase(mode)) {

this.mode=MAX_WORD_LENGTH_MODE;

}

else {

throw new IllegalArgumentException(”不合法的分析器Mode参数设置:” + mode);

}

}

@Override

public void init(Map args) {

super.init(args);

setMode(args.get(”mode”));

}

public TokenStream create(Reader input) {

return new PaodingTokenizer(input, PaodingMaker.make(),

createTokenCollector());

}

private TokenCollector createTokenCollector() {

if( MOST_WORDS_MODE.equals(mode))

return new MostWordsTokenCollector();

if( MAX_WORD_LENGTH_MODE.equals(mode))

return new MaxWordLengthTokenCollector();

throw new Error(”never happened”);

}

}

在schema.xml的字段text配置里加入该分词器。

  1.  
  2.             
  3.  
  4.                 
  5.  
  6.  
  7.                 
  8.  
  9.                 
  10.  
  11.                 
  12.  
  13.  
  14.                 
  15.  
  16.             
  17.  
  18.             
  19.  
  20.                                
  21.  
  22.                 
  23.  
  24.                 
  25.  
  26.                 
  27.  
  28.                 
  29.  
  30.                 
  31.  
  32.             
  33.  
  34.         

完成后重启tomcat,即可在http://localhost:8080/solr/admin/analysis.jsp

体验到庖丁的中文分词。注意要将paoding-analysis.jar复制到solr的lib下,注意修改jar包里字典的home。

[Solr的检索运算符]
 “:” 指定字段查指定值,如返回所有值*:*
 “?” 表示单个任意字符的通配
 “*” 表示多个任意字符的通配(不能在检索的项开始使用*或者?符号)
 “~” 表示模糊检索,如检索拼写类似于”roam”的项这样写:roam~将找到形如foam和roams的单词;roam~0.8,检索返回相似度在0.8以上的记录。
 邻近检索,如检索相隔10个单词的”apache”和”jakarta”,”jakarta apache”~10
 “^” 控制相关度检索,如检索jakarta apache,同时希望去让”jakarta”的相关度更加好,那么在其后加上”^”符号和增量值,即jakarta^4 apache
 布尔操作符AND、||
 布尔操作符OR、&&
 布尔操作符NOT、!、- (排除操作符不能单独与项使用构成查询)
“+” 存在操作符,要求符号”+”后的项必须在文档相应的域中存在
 ( ) 用于构成子查询
 [] 包含范围检索,如检索某时间段记录,包含头尾,date:[200707 TO 200710]
 {} 不包含范围检索,如检索某时间段记录,不包含头尾
date:{200707 TO 200710}
 / 转义操作符,特殊字符包括+ - && || ! ( ) { } [ ] ^ ” ~ * ? : /


推荐阅读
  • YOLOv7基于自己的数据集从零构建模型完整训练、推理计算超详细教程
    本文介绍了关于人工智能、神经网络和深度学习的知识点,并提供了YOLOv7基于自己的数据集从零构建模型完整训练、推理计算的详细教程。文章还提到了郑州最低生活保障的话题。对于从事目标检测任务的人来说,YOLO是一个熟悉的模型。文章还提到了yolov4和yolov6的相关内容,以及选择模型的优化思路。 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • 如何实现织梦DedeCms全站伪静态
    本文介绍了如何通过修改织梦DedeCms源代码来实现全站伪静态,以提高管理和SEO效果。全站伪静态可以避免重复URL的问题,同时通过使用mod_rewrite伪静态模块和.htaccess正则表达式,可以更好地适应搜索引擎的需求。文章还提到了一些相关的技术和工具,如Ubuntu、qt编程、tomcat端口、爬虫、php request根目录等。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 本文讨论了Alink回归预测的不完善问题,指出目前主要针对Python做案例,对其他语言支持不足。同时介绍了pom.xml文件的基本结构和使用方法,以及Maven的相关知识。最后,对Alink回归预测的未来发展提出了期待。 ... [详细]
  • ZSI.generate.Wsdl2PythonError: unsupported local simpleType restriction ... [详细]
  • Android系统移植与调试之如何修改Android设备状态条上音量加减键在横竖屏切换的时候的显示于隐藏
    本文介绍了如何修改Android设备状态条上音量加减键在横竖屏切换时的显示与隐藏。通过修改系统文件system_bar.xml实现了该功能,并分享了解决思路和经验。 ... [详细]
  • 本文介绍了在使用Python中的aiohttp模块模拟服务器时出现的连接失败问题,并提供了相应的解决方法。文章中详细说明了出错的代码以及相关的软件版本和环境信息,同时也提到了相关的警告信息和函数的替代方案。通过阅读本文,读者可以了解到如何解决Python连接服务器失败的问题,并对aiohttp模块有更深入的了解。 ... [详细]
  • Spring常用注解(绝对经典),全靠这份Java知识点PDF大全
    本文介绍了Spring常用注解和注入bean的注解,包括@Bean、@Autowired、@Inject等,同时提供了一个Java知识点PDF大全的资源链接。其中详细介绍了ColorFactoryBean的使用,以及@Autowired和@Inject的区别和用法。此外,还提到了@Required属性的配置和使用。 ... [详细]
  • python限制递归次数(python最大公约数递归)
    本文目录一览:1、python为什么要进行递归限制 ... [详细]
  • 本文介绍了如何使用JSONObiect和Gson相关方法实现json数据与kotlin对象的相互转换。首先解释了JSON的概念和数据格式,然后详细介绍了相关API,包括JSONObject和Gson的使用方法。接着讲解了如何将json格式的字符串转换为kotlin对象或List,以及如何将kotlin对象转换为json字符串。最后提到了使用Map封装json对象的特殊情况。文章还对JSON和XML进行了比较,指出了JSON的优势和缺点。 ... [详细]
  • Activiti7流程定义开发笔记
    本文介绍了Activiti7流程定义的开发笔记,包括流程定义的概念、使用activiti-explorer和activiti-eclipse-designer进行建模的方式,以及生成流程图的方法。还介绍了流程定义部署的概念和步骤,包括将bpmn和png文件添加部署到activiti数据库中的方法,以及使用ZIP包进行部署的方式。同时还提到了activiti.cfg.xml文件的作用。 ... [详细]
  • 本文讨论了在shiro java配置中加入Shiro listener后启动失败的问题。作者引入了一系列jar包,并在web.xml中配置了相关内容,但启动后却无法正常运行。文章提供了具体引入的jar包和web.xml的配置内容,并指出可能的错误原因。该问题可能与jar包版本不兼容、web.xml配置错误等有关。 ... [详细]
  • 目录浏览漏洞与目录遍历漏洞的危害及修复方法
    本文讨论了目录浏览漏洞与目录遍历漏洞的危害,包括网站结构暴露、隐秘文件访问等。同时介绍了检测方法,如使用漏洞扫描器和搜索关键词。最后提供了针对常见中间件的修复方式,包括关闭目录浏览功能。对于保护网站安全具有一定的参考价值。 ... [详细]
  • Java如何导入和导出Excel文件的方法和步骤详解
    本文详细介绍了在SpringBoot中使用Java导入和导出Excel文件的方法和步骤,包括添加操作Excel的依赖、自定义注解等。文章还提供了示例代码,并将代码上传至GitHub供访问。 ... [详细]
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社区 版权所有