`

Lucene/Solr开发经验

阅读更多

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分词原理演示界面

[渊源]最初,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服务器可以存储数据并通过索引对其进行快速高效检索。对外提供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不具备安全性设计,没有用户组及权限设置,在进行具体应用时需要注意安全,目前最有效的方法是通过应

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

solr包下载地址:http://apache.etoak.com/lucene/solr

要开始使用 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,文件内容如下:

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

<server ...>
 <service ...>
   <connector ... URIEncoding="UTF-8"/>
     ...
 </service>
</server>
[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中加入如下配置:

<fieldtype name="text_cjk" class="solr.TextField">
      <analyzer class="org.apache.lucene.analysis.cjk.CJKAnalyzer"/>
    </fieldtype>
支持类型定义完成了。

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

<field name="记录号" type="slong" indexed="true" stored="true" required="true" />
   <field name="文件名" type="string" indexed="true" stored="true" />
   <field name="日期" type="date" indexed="true" stored="true" />
   <field name="版次" type="string" indexed="true" stored="true" multiValued="true"/>
   <field name="栏目" type="string" indexed="true" stored="true" multiValued="true"/>
   <field name="标题" type="text_cjk" indexed="true" stored="true" multiValued="true"/>
   <field name="作者" type="text_cjk" indexed="true" stored="true" multiValued="true"/>
   <field name="正文" type="text_cjk" indexed="true" stored="true" multiValued="true"/>
   <field name="标记" type="text_cjk" indexed="true" stored="true" multiValued="true"/>
field的定义相当重要,有几个技巧需注意一下,对可能存在多值得字段尽量设置multiValued属性为true,避免建索引是抛出错误;如果不需要存储相应字段值,尽量将stored属性设为false。

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

<field name="text_com" type="text_cjk" indexed="true" stored="false" multiValued="true"/>
并在拷贝字段结点处完成拷贝设置:

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

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

<autocommit>
    <maxdocs>200000</maxdocs>
  </autocommit>
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配置里加入该分词器。

<fieldtype name="text" class="solr.TextField" positionIncrementGap="100">
 
            <analyzer type="index">
 
                <tokenizer class="com.ronghao.fulltextsearch.analyzer.ChineseTokenizerFactory" mode="most-words"/>
 
 
                <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt"/>
 
                <filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="1" catenateNumbers="1" catenateAll="0"/>
 
                <filter class="solr.LowerCaseFilterFactory"/>
 
 
                <filter class="solr.RemoveDuplicatesTokenFilterFactory"/>
 
            </analyzer>
 
            <analyzer type="query">
 
                <tokenizer class="com.ronghao.fulltextsearch.analyzer.ChineseTokenizerFactory" mode="most-words"/>               
 
                <filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
 
                <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt"/>
 
                <filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="0" catenateNumbers="0" catenateAll="0"/>
 
                <filter class="solr.LowerCaseFilterFactory"/>
 
                <filter class="solr.RemoveDuplicatesTokenFilterFactory"/>
 
            </analyzer>
 
        </fieldtype>
完成后重启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}
 \ 转义操作符,特殊字符包括+ - && || ! ( ) { } [ ] ^ ” ~ * ? : \

分享到:
评论

相关推荐

    lucene,solr的使用

    ### Lucene与Solr的使用详解 #### 一、Lucene概述 Lucene是一款高性能、全功能的文本搜索引擎库,由Java语言编写而成。它能够为应用系统提供强大的全文检索能力,是当前最为流行的开源搜索库之一。由于其高度可...

    Lucene&solr.zip

    Lucene是一个由Apache软件基金会开发的全文检索库,它提供了高效的、可扩展的文本搜索功能。Lucene的核心功能包括索引创建、文档检索、查询解析和结果排序。它的主要特点包括: - **分词**:Lucene内置了多种分词器...

    IKAnalyzer 适用 lucene和solr 5.4.0版本

    3. **配置Lucene或Solr**:将生成的jar包添加到Lucene或Solr的lib目录下,然后在相应配置文件中指定IKAnalyzer为Analyzer。 4. **测试与应用**:编写测试代码验证IKAnalyzer的分词效果,确认无误后即可在实际项目中...

    IK分词器-Lucene与Solr学习中使用

    IK分词器是Java开发的一款高效、灵活的中文分词工具,特别适用于Lucene和Solr等全文搜索引擎的中文处理。在对文本进行索引和搜索时,分词器的作用至关重要,它能将中文文本拆分成有意义的词汇,以便进行后续的分析和...

    Solr搜索引擎

    它基于 **Apache Lucene** 开发,提供了丰富的功能集,包括全文检索、文档排序、过滤等。Solr 作为企业级搜索平台,其主要优势在于高度可扩展性、易用性和灵活性。 #### Solr的下载与安装 1. **下载** - 官网地址...

    lucene索引查看工具luke8.0

    luke是一个用于Lucene/Solr/Elasticsearch 搜索引擎,方便开发和诊断的 GUI(可视化)工具。

    IK中文分词器2012版支持Lucene和solr

    - Lucene是Apache软件基金会的一个开源项目,是一个高性能、全文本检索库,为开发人员提供了强大的文本检索功能。 - Solr是基于Lucene构建的全文搜索服务器,提供了一种分布式、可配置、易扩展的搜索解决方案。 -...

    lucene、solr中文分词器

    在构建高效的全文搜索引擎时,Apache Lucene 和 Solr 是两个非常重要的开源库。它们提供了强大的信息检索和文本分析功能,但Lucene默认的分词器并不适用于中文处理。因此,对于中文索引和搜索,我们需要引入专门针对...

    搜索引擎解密Lucene与Solr的前世今生.ppt

    《搜索引擎解密:Lucene与Solr的前世今生》 搜索引擎是互联网信息时代的重要工具,它们使得海量数据的检索变得高效、便捷。本篇将深入探讨两款广泛应用的开源搜索引擎技术——Lucene和Solr,揭示它们的核心原理以及...

    IKAnalyzer 适用 lucene和solr 5.4.0版本(新)

    IKAnalyzer 是一个专门为中文分词设计的开源分析器,它在 Lucene 和 Solr 中广泛使用,以提高中文文本检索的准确性和效率。这个压缩包 "ik-analyzer-solr5.4.0" 显然是针对 Lucene 5.4.0 和 Solr 5.4.0 版本优化的 ...

    tomcat和solr的配置安装过程

    Tomcat 是一个开源的 Web 服务器软件,而 Solr 是一个基于 Lucene 的搜索服务器。它们都是 Java 语言开发的,因此可以在多种操作系统上运行。 一、Tomcat 的安装配置 首先,我们需要下载 Tomcat 的安装包。可以到 ...

    solr企业级搜索引擎准备阶段

    Apache Solr 是一个开源的搜索服务器,Solr 使用 Java 语言开发,主要基于 HTTP 和 Apache Lucene 实现. Solr 运行在Java的Servlet容器上,诸如: Tomcat or Jetty。 Solr 是一个免费的开源搜索引擎免费软件。 Solr ...

    lucene solr框架代码实例(可直接运行)

    在实际开发中,结合Java编程,我们可以利用SolrJ客户端库与Solr服务器进行交互,实现对索引的创建、更新和删除,以及发起各种查询请求。SolrJ封装了与Solr服务器通信的细节,让开发者可以专注于业务逻辑,而不是底层...

    solr开发指南.pdf

    ### Solr开发指南知识点概述 #### 一、Solr简介 **1.1.1 官网介绍** Solr是一款由Apache基金会维护的开源搜索引擎服务器,其核心是基于Lucene的Java实现。Solr提供了丰富的功能,如层级搜索、命中高亮显示、支持...

    lucene-solr-sandbox:Apache Lucene和Solr开源搜索软件插件模块沙箱

    "lucene-solr-sandbox"是这两个项目的试验田,用于测试新的特性和模块,它为开发者提供了一个安全的环境来探索、实验和开发潜在的新功能。 在"lucene-solr-sandbox"中,你可以找到各种实验性的搜索技术和插件,这些...

    lucene简单介绍及solr搭建使用

    Lucene是Java开发的一个全文检索库,而Solr则是基于Lucene构建的企业级搜索平台,提供了更高级的功能和管理界面。 **Lucene简介** Lucene是Apache软件基金会的一个项目,它提供了一个强大的文本分析和索引框架,...

    solr的学习

    - **定义**:Solr 是 Apache 下的一个顶级开源项目,采用 Java 开发,它是基于 Lucene 的全文搜索服务器。Solr 可以独立运行在 Jetty、Tomcat 等 Servlet 容器中。 - **特点**: - 提供了比 Lucene 更为丰富的查询...

Global site tag (gtag.js) - Google Analytics