Solr调研总结:

1. Solr 是什么?

Solr它是一种开放源码的、基于 Lucene Java 的搜索服务器,易于加入到 Web 应用程序中。Solr 提供了层面搜索(就是统计)、命中醒目显示并且支持多种输出格式(包括XML/XSLT 和JSON等格式)。它易于安装和配置,而且附带了一个基于HTTP 的管理界面。可以使用 Solr 的表现优异的基本搜索功能,也可以对它进行扩展从而满足企业的需要。Solr的特性包括:

  • 高级的全文搜索功能
  • 专为高通量的网络流量进行的优化
  • 基于开放接口(XML和HTTP)的标准
  • 综合的HTML管理界面
  • 可伸缩性-能够有效地复制到另外一个Solr搜索服务器
  • 使用XML配置达到灵活性和适配性
  • 可扩展的插件体系

2. Lucene 是什么?

Lucene是一个基于Java的全文信息检索工具包,它不是一个完整的搜索应用程序,而是为你的应用程序提供索引和搜索功能。Lucene 目前是 Apache Jakarta(雅加达) 家族中的一个开源项目。也是目前最为流行的基于Java开源全文检索工具包。目前已经有很多应用程序的搜索功能是基于 Lucene ,比如Eclipse 帮助系统的搜索功能。Lucene能够为文本类型的数据建立索引,所以你只要把你要索引的数据格式转化的文本格式,Lucene 就能对你的文档进行索引和搜索。

3. Solr vs Lucene

Solr与Lucene 并不是竞争对立关系,恰恰相反Solr 依存于Lucene,因为Solr底层的核心技术是使用Lucene 来实现的,Solr和Lucene的本质区别有以下三点:搜索服务器,企业级和管理。Lucene本质上是搜索库,不是独立的应用程序,而Solr是。Lucene专注于搜索底层的建设,而Solr专注于企业应用。Lucene不负责支撑搜索服务所必须的管理,而Solr负责。所以说,一句话概括 Solr: Solr是Lucene面向企业搜索应用的扩展。

Solr与Lucene架构图:

solr教程-LMLPHP

Solr使用Lucene并且扩展了它!

  • 一个真正的拥有动态字段(Dynamic Field)和唯一键(Unique Key)的数据模式(Data Schema)
  • 对Lucene查询语言的强大扩展!
  • 支持对结果进行动态的分组和过滤
  • 高级的,可配置的文本分析
  • 高度可配置和可扩展的缓存机制
  • 性能优化
  • 支持通过XML进行外部配置
  • 拥有一个管理界面
  • 可监控的日志
  • 支持高速增量式更新(Fast incremental Updates)和快照发布(Snapshot Distribution)

4.搭建并调试Solr

4.1 安装虚拟机

Solr 必须运行在Java1.6 或更高版本的Java 虚拟机中,运行标准Solr 服务只需要安装JRE 即可,但如果需要扩展功能或编译源码则需要下载JDK 来完成。可以通过下面的地址下载所需JDK 或JRE :

安装 步骤请参考相应的帮助文档。

4.2下载Solr

本文针对Solr4.2版本进行调研的,下文介绍内容均针对Solr4.2版本,如与Solr 最新版本有出入请以官方网站内容为准。Solr官方网站下载地址:http://lucene.apache.org/solr/

4.3下载并设置Apache Ant

Solr是使用Ant进行管理的源码, Ant是一种基于Java的build工具。理论上来说,它有些类似于Maven 或者是 C中的make。下载后解压出来后,进行环境变量设置。

ANT_HOME:E:\Work\apache-ant\1.9.1 (这里为你自己解压缩的目录) PATH:%ANT_HOME%\bin (这个设置是为了方便在dos环境下操作)

查看是否安装成功,在命令行窗口中输入命令ant,若出现结果:

solr教程-LMLPHP

说明ant安装成功!因为ant默认运行build.xml文件,这个文件需要我们建立。现在就可以进行build Solr源码了。在命令行窗口中进入到你的Solr源码目录,输入ant会出现当前build.xml使用提示信息。

solr教程-LMLPHP

其它的先不用管它,我们只要针对我们使用的IDE进行build就行了,如果使用eclipse就在命令行输入:ant eclipse.如果使用IntelliJ IDEA 就在命令行输入:ant idea。这样就能进行build了。

黑窗口里提示这个。。。

solr教程-LMLPHP

失败。。。为什么呢,最后我发现是因为下载的ant中少了一个jar就是这apache-ivy(下载地址:http://ant.apache.org/ivy/)这东东名子真怪 ivy是ant管理jar依赖关系的。当第一次bulid时ivy会自动把build中的缺少的依赖进行下载。网速慢的第一次build要好久的。。。

下载一个jar就行把jar放到ant的lib下(E:\Work\apache-ant\1.9.1\lib)这样再次运行ant 就会成功了。到现在才可以进行Solr的代码调试。

4.4配置并运行Solr代码

不管用什么IDE首选都要设置Solr Home在IDE的JVM参数设置VM arguments写入 -Dsolr.solr.home=solr/example/solr一般就行了.不行也可以使用绝对路径.

solr使用StartSolrJetty文件作为入口文件进行调试代码,在这里可以设置服务器使用的端口和solr的webapps目录.一般都不用设置,默认的就可以进行调试.Solr Home也能可在代码中设置一样好用.  System.setProperty("solr.solr.home", "E:\\Work\\solr-4.2.0-src-idea\\solr\\example\\solr");

目前是使用自带的一个example作为solr配置的根目录,如果你有其他的solr配置目录,设置之即可。点击run即可,debug也是一样可以用了。没有别的问题就应该能运行了.注意servlet 容器使用的端口,如查提示:

FAILED SocketConnector@0.0.0.0:8983: java.net.BindException: Address already in use: JVM_Bind 就说明当前端口占用中.改一下就可以了.如果没有报错启动成功后就可以在浏览器中输入地址:http://localhost:8983/solr/ 就可以看到如下界面

solr教程-LMLPHP

到这里Solr就成功配置并运行了.要是想跟代码调试在启动时在这个方法里点断点就可以Initializer的initialize()方法如果想从浏览器中找断点调试就要到SolrDispatchFilter的doFilter方法中点断点了.

注:IE9在兼容模式下有bug,必须设置为非兼容模式。

5.Solr基础

因为 Solr 包装并扩展了Lucene,所以它们使用很多相同的术语。更重要的是,Solr 创建的索引与 Lucene 搜索引擎库完全兼容。通过对 Solr 进行适当的配置,某些情况下可能需要进行编码,Solr 可以阅读和使用构建到其他 Lucene 应用程序中的索引。在 Solr 和 Lucene 中,使用一个或多个 Document 来构建索引。Document 包括一个或多个 Field。Field 包括名称、内容以及告诉 Solr 如何处理内容的元数据。

例如,Field 可以包含字符串、数字、布尔值或者日期,也可以包含你想添加的任何类型,只需用在solr的配置文件中进行相应的配置即可。Field 可以使用大量的选项来描述,这些选项告诉 Solr 在索引和搜索期间如何处理内容。

现在,查看一下表 1 中列出的重要属性的子集:

5.1模式配置Schema.xml

schema.xml这个配置文件可以在你下载solr包的安装解压目录的\solr\example\solr\collection1\conf中找到,它就是solr模式关联的文件。打开这个配置文件,你会发现有详细的注释。模式组织主要分为三个重要配置

5.1.1. types 部分

是一些常见的可重用定义,定义了 Solr(和 Lucene)如何处理 Field。也就是添加到索引中的xml文件属性中的类型,如int、text、date等.

  1. <fieldType name="string" class="solr.StrField" sortMissingLast="true"/>
  2. <fieldType name="boolean" class="solr.BoolField" sortMissingLast="true"/>
  3. <fieldType name="int" class="solr.TrieIntField" precisionStep="0" positionIncrementGap="0"/>
  1. <fieldType name="text_general" class="solr.TextField" positionIncrementGap="100">
  2. <analyzer type="index">
  3. <tokenizer class="solr.StandardTokenizerFactory"/>
  4. <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" enablePositionIncrements="true" />
  5. <filter class="solr.LowerCaseFilterFactory"/>
  6. </analyzer>
  7. <analyzer type="query">
  8. <tokenizer class="solr.StandardTokenizerFactory"/>
  9. <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" enablePositionIncrements="true" />
  10. <filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
  11. <filter class="solr.LowerCaseFilterFactory"/>
  12. </analyzer>
  13. </fieldType>

参数说明:

5.1.2. fileds

是你添加到索引文件中出现的属性名称,而声明类型就需要用到上面的types

  1. <field name="id" type="string" indexed="true" stored="true" required="true" multiValued="false"/>
  2. <field name="path" type="text_smartcn" indexed="false" stored="true" multiValued="false" termVector="true" />
  3. <field name="content" type="text_smartcn" indexed="false" stored="true" multiValued="false" termVector="true"/>
  4. <field name ="text" type ="text_ik" indexed ="true" stored ="false" multiValued ="true"/>
  5. <field name ="pinyin" type ="text_pinyin" indexed ="true" stored ="false" multiValued ="false"/>
  6. <field name="_version_" type="long" indexed="true" stored="true"/>
  1. <dynamicField name="*_i" type="int" indexed="true" stored="true"/>
  2. <dynamicField name="*_l" type="long" indexed="true" stored="true"/>
  3. <dynamicField name="*_s" type="string" indexed="true" stored="true" />
  • field: 固定的字段设置
  • dynamicField: 动态的字段设置,用于后期自定义字段,*号通配符.例如: test_i就是int类型的动态字段.

还有一个特殊的字段copyField,一般用于检索时用的字段这样就只对这一个字段进行索引分词就行了copyField的dest字段如果有多个source一定要设置multiValued=true,否则会报错的

  1. <copyField source="content" dest="pinyin"/>
  2. <copyField source="content" dest="text"/>
  3. <copyField source="pinyin" dest="text"/>

字段属性说明:

注意:_version_ 是一个特殊字段,不能删除,是记录当前索引版本号的.

5.1.3. 其他配置

uniqueKey: 唯一键,这里配置的是上面出现的fileds,一般是id、url等不重复的。在更新、删除的时候可以用到。

defaultSearchField:默认搜索属性,如q=solr就是默认的搜索那个字段

solrQueryParser:查询转换模式,是并且还是或者(AND/OR必须大写)

5.2. solr配置solrconfig.xml

solrconfig.xml这个配置文件可以在你下载solr包的安装解压目录的E:\Work\solr-4.2.0-src-idea\solr\example\solr\collection1\conf中找到,这个配置文件内容有点多,主要内容有:使用的lib配置,包含依赖的jar和Solr的一些插件;组件信息配置;索引配置和查询配置,下面详细说一下索引配置和查询配置.

5.2.1索引indexConfig

       Solr 性能因素,来了解与各种更改相关的性能权衡。 表 1 概括了可控制 Solr 索引处理的各种因素:

5.2.2 查询配置query

5.3Solr加入中文分词器

     中文分词在solr里面是没有默认开启的,需要我们自己配置一个中文分词器。目前可用的分词器有smartcn,IK,Jeasy,庖丁。其实主要是两种,一种是基于中科院ICTCLAS的隐式马尔科夫HMM算法的中文分词器,如smartcn,ictclas4j,优点是分词准确度高,缺点是不能使用用户自定义词库;另一种是基于最大匹配的分词器,如IK ,Jeasy,庖丁,优点是可以自定义词库,增加新词,缺点是分出来的垃圾词较多。各有优缺点看应用场合自己衡量选择吧。

       下面给出两种分词器的安装方法,任选其一即可,推荐第一种,因为smartcn就在solr发行包的contrib/analysis-extras/lucene-libs/下,就是lucene-analyzers-smartcn-4.2.0.jar,首选在solrconfig.xml中加一句引用analysis-extras的配置,这样我们自己加入的分词器才会引到的solr中.

<lib dir="../../../contrib/analysis-extras/lib" regex=".*\.jar" />

5.3.1. smartcn 分词器的安装

    首选将发行包的contrib/analysis-extras/lucene-libs/ lucene-analyzers-smartcn-4.2.0.jar复制到\solr\contrib\analysis-extras\lib下,在solr本地应用文件夹下,打开/solr/conf/scheme.xml,编辑text字段类型如下,添加以下代码到scheme.xml中的相应位置,就是找到fieldType定义的那一段,在下面多添加这一段就好啦

  1. <fieldType name="text_smartcn" class="solr.TextField" positionIncrementGap="0">
  2. <analyzer type="index">
  3. <tokenizer class="org.apache.lucene.analysis.cn.smart.SmartChineseSentenceTokenizerFactory"/>
  4. <filter class="org.apache.lucene.analysis.cn.smart.SmartChineseWordTokenFilterFactory"/>
  5. </analyzer>
  6. <analyzer type="query">
  7. <tokenizer class="org.apache.lucene.analysis.cn.smart.SmartChineseSentenceTokenizerFactory"/>
  8. <filter class="org.apache.lucene.analysis.cn.smart.SmartChineseWordTokenFilterFactory"/>
  9. </analyzer>
  10. </fieldType>

       如果需要检索某个字段,还需要在scheme.xml下面的field中,添加指定的字段,用text_ smartcn作为type的名字,来完成中文分词。如 text要实现中文检索的话,就要做如下的配置:

<field name ="text" type ="text_smartcn" indexed ="true" stored ="false" multiValued ="true"/>

5.3.2. IK 分词器的安装

首选要去下载IKAnalyzer的发行包.下载地址: http://ik-analyzer.googlecode.com/files/IK%20Analyzer%202012FF_hf1.zip.

下载后解压出来文件中的三个复制到\solr\contrib\analysis-extras\lib目录中.

IKAnalyzer2012FF_u1.jar       分词器jar包

IKAnalyzer.cfg.xml                 分词器配置文件

Stopword.dic                           分词器停词字典,可自定义添加内容

复制后就可以像smartcn一样的进行配置scheme.xml了.

  1. <fieldType name="text_ik" class="solr.TextField">
  2. <analyzer class="org.wltea.analyzer.lucene.IKAnalyzer"/>
  3. </fieldType>
<field name ="text" type ="text_ik" indexed ="true" stored ="false" multiValued ="true"/>

       现在来验证下是否添加成功,首先使用StartSolrJetty来启动solr服务,启动过程中如果配置出错,一般有两个原因:一是配置的分词器jar找不到,也就是你没有复制jar包到\solr\contrib\analysis-extras\lib目前下;二是分词器版本不对导致的分词器接口API不一样出的错,要是这个错的话就在检查分词器的相关文档,看一下支持的版本是否一样.

       如果在启动过程中没有报错的话说明配置成功了.我们可以进入到http://localhost:8983/solr地址进行测试一下刚加入的中文分词器.在首页的Core Selector中选择你配置的Croe后点击下面的Analysis,在Analyse Fieldname / FieldType里选择你刚才设置的字段名称或是分词器类型,在Field Value(index)中输入:中国人,点击右面的分词就行了.

6.Solr功能应用

       我这里主要使用SolrJ进行介绍一下Solr的一些基本应用,使用SolrJ加上EmbeddedSolrServer(嵌入式服务器),方便进行代码跟踪调试.在功能上和其它服务器都是一样的,它们都是继承的SolrServer来提供服务API的. EmbeddedSolrServer优点是不用起http协议,直接加载SolrCore进行操作,性能上应该是最快的,方便用于把Solr单结点服务嵌入到项目中使用.下面开始介绍Solr的功能的应用.EmbeddedSolrServer初始化:

  1. System.setProperty("solr.solr.home", "E:\\Work\\solr-4.2.0-src\\solr\\example\\solr");
  2. CoreContainer.Initializer initializer = new CoreContainer.Initializer();
  3. CoreContainer coreContainer = initializer.initialize();
  4. SolrServer server = new EmbeddedSolrServer(coreContainer, "");

6.1维护索引

       在一般系统中维护的都是增删改,在Solr中的维护功能是增删和优化功能,在Solr中的修改操作就是先删掉再添加.在做索引维护之前,首先要做的是配置schema.xml主要是按上面章节中的说明设置好字段信息(名称,类型,索引,存储,分词等信息),大概就像在数据库中新建一个表一样.设置好schema.xml就可以进行索引相关操作了.

6.1.1增加索引

       在增加索引之前先可构建好SolrInputDocument对象.主要操作就是给文档添加字段和值.代码如下:

  1. SolrInputDocument doc = new SolrInputDocument();
  2. doc.setField("id", "ABC");
  3. doc.setField("content", "中华人民共和国");

构建好文档后添加的上面初始化好的server里就行了.

  1. server.add(doc);
  2. server.commit();//这句一般不用加因为我们可以通过在配置文件中的
  3. //autoCommit来提高性能

       Solr在add文档时.如果文档不存在就直接添加,如果文档存在就删除后添加,这也就是修改功能了.判断文档是否存在的依据是定义好的uniqueKey字段.

6.1.2删除索引

       删除索引可以通过两种方式操作,一种是通过文档ID进行删除,别一种是通过查询到的结果进行删除.

通过ID删除方式代码:

  1. server.deleteById(id);
  2. //或是使用批量删除
  3. server.deleteById(ids);

通过查询删除方式代码:

  1. server.deleteByQuery("*.*");//这样就删除了所有文档索引
  2. //”*.*”就查询所有内容的,介绍查询时会详细说明.

6.1.2优化索引

       优化Lucene 的索引文件以改进搜索性能。索引完成后执行一下优化通常比较好。如果更新比较频繁,则应该在使用率较低的时候安排优化。一个索引无需优化也可以正常地运行。优化是一个耗时较多的过程。

  server.optimize();//不要频繁的调用..尽量在无人使用时调用.

6.2查询索引

       Solr在不修改任务配置的情况下就可以使用查询功能,在web项目中应用可以直接URL进行访问Solr服务器例如 :

http://localhost:8983/solr/ collection1/select?q=*%3A*&wt=xml&indent=true

       上面的意思就是查询名为collection1的SolrCore的所有内容用xml格式返回并且有缩进。

返回结果如下:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <response>
  3. <lst name="responseHeader">
  4. <int name="status">0</int>
  5. <int name="QTime">0</int>
  6. <lst name="params">
  7. <str name="indent">true</str>
  8. <str name="q">*:*</str>
  9. <str name="wt">xml</str>
  10. </lst>
  11. </lst>
  12. <result name="response" numFound="17971" start="0">
  13. <doc>
  14. <str name="path">E:\Reduced\军事\1539.txt</str>
  15. <str name="category_s">2</str>
  16. <int name="browseCount_i">-1423701734</int>
  17. <long name="modified_l">1162438568000</long>
  18. <long name="releasedate_l">1162438568000</long>
  19. <str name="content"> [俄罗斯lenta网站2006年2月9日报道]俄空军副总司令比热耶夫中将称,2006年春天独联体国家防空系统打击范围向西推进150千米,侦察范围向西推进400千米。  2006年3月白俄罗斯4个S-300PS防空导弹营担负战斗任务,使独联体防空系统作战范围得以向西推进。比热耶夫中将还宣布,近期乌兹别克斯坦可能加入独联体防空系统。  独联体国家防空系统建于9年前,共有9个国家参加该组织。目前只有亚美尼亚、白俄罗斯、哈萨克斯坦、吉尔吉斯、俄罗斯和塔吉克斯坦支持该体系。  乌克兰、乌兹别克斯坦与俄罗斯在双边基础上合作,格鲁吉亚和土库曼最近7年不参加独联体国家对空防御。</str>
  20. <str name="id">E3798D82-EAB6-2BEA-D7E2-79FBD102E845</str>
  21. <long name="_version_">1436361868021071872</long></doc>
  22. </result>
  23. </response>

上面所看到的就是用xml格式返回的查询结果,其中的doc就是一个文档,在doc里面的那个就是我们开始在schema.xml中定义的字段.

如果使用SolrJ进行调用的话代码如下:

  1. SolrQuery query = new SolrQuery();
  2. query.set("q","*.*");
  3. QueryResponse rsp =server.query(query)
  4. SolrDocumentList list = rsp.getResults();

返回结果在SolrDocumentList中在这个对象中遍历取出值来:

  1. for (int i = 0; i < list.size(); i++) {
  2. SolrDocument sd = list.get(i);
  3. String id = (String) sd.getFieldValue("id");
  4. System.out.println(id);
  5. }

6.2.1查询参数

6.2.2查询语法

  1. 1.匹配所有文档:*:*
  2. 2.强制、阻止和可选查询:
  3. 1) Mandatory:查询结果中必须包括的(for example, only entry name containing the word make)
  4. Solr/Lucene Statement:+make, +make +up ,+make +up +kiss
  5. 2) prohibited:(for example, all documents except those with word believe)
  6. Solr/Lucene Statement:+make +up -kiss
  7. 3) optional:
  8. Solr/Lucene Statement:+make +up kiss
  9. 3.布尔操作:ANDORNOT布尔操作(必须大写)与Mandatory、optional和prohibited相似。
  10. 1) make AND up = +make +up :AND左右两边的操作都是mandatory
  11. 2) make || up = make OR up=make up :OR左右两边的操作都是optional
  12. 3) +make +up NOT kiss = +make +up –kiss
  13. 4) make AND up OR french AND Kiss不可以达到期望的结果,因为AND两边的操作都是mandatory的。
  14. 4. 子表达式查询(子查询):可以使用“()”构造子查询。
  15. 示例:(make AND up) OR (french AND Kiss)
  16. 5.子表达式查询中阻止查询的限制:
  17. 示例:make (-up):只能取得make的查询结果;要使用make (-up *:*)查询make或者不包括up的结果。
  18. 6.多字段fields查询:通过字段名加上分号的方式(fieldName:query)来进行查询
  19. 示例:entryNm:make AND entryId:3cdc86e8e0fb4da8ab17caed42f6760c
  20. 7.通配符查询(wildCard Query):
  21. 1) 通配符?和*:“*”表示匹配任意字符;“?”表示匹配出现的位置。
  22. 示例:ma?*(ma后面的一个位置匹配),ma??*(ma后面两个位置都匹配)
  23. 2) 查询字符必须要小写:+Ma +be**可以搜索到结果;+Ma +Be**没有搜索结果.
  24. 3) 查询速度较慢,尤其是通配符在首位:主要原因一是需要迭代查询字段中的每个term,判断是否匹配;二是匹配上的term被加到内部的查询,当terms数量达到1024的时候,查询会失败。
  25. 4) Solr中默认通配符不能出现在首位(可以修改QueryParser,设置
  26. setAllowLeadingWildcard为true
  27. 5) set setAllowLeadingWildcard to true.
  28. 8.模糊查询、相似查询:不是精确的查询,通过对查询的字段进行重新插入、删除和转换来取得得分较高的查询解决(由Levenstein Distance Algorithm算法支持)。
  29. 1) 一般模糊查询:示例:make-believ~
  30. 2) 门槛模糊查询:对模糊查询可以设置查询门槛,门槛是0~1之间的数值,门槛越高表面相似度越高。示例:make-believ~0.5、make-believ~0.8、make-believ~0.9
  31. 9.范围查询(Range Query):Lucene支持对数字、日期甚至文本的范围查询。结束的范围可以使用“*”通配符。
  32. 示例:
  33. 1) 日期范围(ISO-8601 时间GMT):sa_type:2 AND a_begin_date:[1990-01-01T00:00:00.000Z TO 1999-12-31T24:59:99.999Z]
  34. 2) 数字:salary:[2000 TO *]
  35. 3) 文本:entryNm:[a TO a]
  36. 10.日期匹配:YEAR, MONTH, DAY, DATE (synonymous with DAY) HOUR, MINUTE, SECOND, MILLISECOND, and MILLI (synonymous with MILLISECOND)可以被标志成日期。
  37. 示例:
  38. 1) r_event_date:[* TO NOW-2YEAR]:2年前的现在这个时间
  39. 2) r_event_date:[* TO NOW/DAY-2YEAR]:2年前前一天的这个时间

6.2.3函数查询(Function Query)

       函数查询 可以利用 numeric字段的值 或者 与字段相关的的某个特定的值的函数,来对文档进行评分。

  1. 1. 使用函数查询的方法
  2. 这里主要有三种方法可以使用函数查询,这三种s方法都是通过solr http接口的。
  3. 1) 使用FunctionQParserPlugin。ie: q={!func}log(foo)
  4. 2) 使用“_val_”内嵌方法
  5. 内嵌在正常的solr查询表达式中。即,将函数查询写在 q这个参数中,这时候,我们使用“_val_”将函数与其他的查询加以区别。
  6. ie:entryNm:make && _val_:ord(entryNm)
  7. 3) 使用dismax中的bf参数
  8. 使用明确为函数查询的参数,比如说dismax中的bf(boost function)这个参数。 注意:bf这个参数是可以接受多个函数查询的,它们之间用空格隔开,它们还可以带上权重。所以,当我们使用bf这个参数的时候,我们必须保证单个函数中是没有空格出现的,不然程序有可能会以为是两个函数。
  9. 示例:
  10. q=dismax&bf="ord(popularity)^0.5 recip(rord(price),1,1000,1000)^0.3
  11. 2. 函数的格式(Function Query Syntax)
  12. 目前,function query 并不支持 a+b 这样的形式,我们得把它写成一个方法形式,这就是 sum(a,b).
  13. 3. 使用函数查询注意事项
  14. 1) 用于函数查询的field必须是被索引的;
  15. 2) 字段不可以是多值的(multi-value)
  16. 4. 可以利用的函数 (available function)
  17. 1) constant:支持有小数点的常量; 例如:1.5 ;SolrQuerySyntax:_val_:1.5
  18. 2) fieldvalue:这个函数将会返回numeric field的值,这个字段必须是indexd的,非multiValued的。格式很简单,就是该字段的名字。如果这个字段中没有这样的值,那么将会返回0。
  19. 3) ord:对于一个字段,它所有的值都将会按照字典顺序排列,这个函数返回你要查询的那个特定的值在这个顺序中的排名。这个字段,必须是非multiValued的,当没有值存在的时候,将返回0。例如:某个特定的字段只能去三个值,“apple”、“banana”、“pear”,那么ord(“apple”)=1,ord(“banana”)=2,ord(“pear”)=3.需要注意的是,ord()这个函数,依赖于值在索引中的位置,所以当有文档被删除、或者添加的时候,ord()的值就会发生变化。当你使用MultiSearcher的时候,这个值也就是不定的了。
  20. 4) rord:这个函数将会返回与ord相对应的倒排序的排名。
  21. 格式: rord(myIndexedField)。
  22. 5) sum:这个函数的意思就显而易见啦,它就是表示“和”啦。
  23. 格式:sum(x,1) 、sum(x,y)、 sum(sqrt(x),log(y),z,0.5)
  24. 6) product:product(x,y,...)将会返回多个函数的乘积。格式:product(x,2)、product(x,y)
  25. 7) div:div(x,y)表示x除以y的值,格式:div(1,x)、div(sum(x,100),max(y,1))
  26. 8) pow:pow表示幂值。pow(x,y) =x^y。例如:pow(x,0.5) 表示开方pow(x,log(y))
  27. 9) abs:abs(x)将返回表达式的绝对值。格式:abs(-5)、 abs(x)
  28. 10) log:log(x)将会返回基数为10,x的对数。格式: log(x)、 log(sum(x,100))
  29. 11) Sqrt:sqrt(x) 返回 一个数的平方根。格式:sqrt(2)、sqrt(sum(x,100))
  30. 12) Map:如果 x>=min,且x<=max,那么map(x,min,max,target)=target.如果 x不在[min,max]这个区间内,那么map(x,min,max,target)=x.
  31. 格式:map(x,0,0,1)
  32. 13) Scalescale(x,minTarget,maxTarget) 这个函数将会把x的值限制在[minTarget,maxTarget]范围内。
  33. 14) queryquery(subquery,default)将会返回给定subquery的分数,如果subquery与文档不匹配,那么将会返回默认值。任何的查询类型都是受支持的。可以通过引用的方式,也可以直接指定查询串。
  34. 例子:q=product(popularity, query({!dismax v='solr rocks'}) 将会返回popularity和通过dismax 查询得到的分数的乘积。
  35. q=product(popularity, query($qq)&qq={!dismax}solr rocks 跟上一个例子的效果是一样的。不过这里使用的是引用的方式
  36. q=product(popularity, query($qq,0.1)&qq={!dismax}solr rocks 在前一个例子的基础上又加了一个默认值。
  37. 15) linearinear(x,m,c)表示 m*x+c ,其中mc都是常量,x是一个变量也可以是一个函数。例如: linear(x,2,4)=2*x+4.
  38. 16) Reciprecip(x,m,a,b)=a/(m*x+b)其中,m、a、b是常量,x是变量或者一个函数。当a=b,并且x>=0的时候,这个函数的最大值是1,值的大小随着x的增大而减小。例如:recip(rord(creationDate),1,1000,1000)
  39. 17) Max: max(x,c)将会返回一个函数和一个常量之间的最大值。
  40. 例如:max(myfield,0)

6.3高亮显示

      我们经常使用搜索引擎,比如在baidu 搜索 java ,会出现如下结果,结果中与关键字匹配的地方是红色显示与其他内容区别开来。

solr 默认已经配置了highlight 组件(详见 SOLR_HOME/conf/sorlconfig.xml)。通常我出只需要这样请求http://localhost:8983/solr/ collection1 /select? q=%E4%B8%AD%E5%9B%BD&start=0&rows=1&fl=content+path+&wt=xml&indent=true&hl=true&hl.fl=content

       可以看到与比一般的请求多了两个参数 "hl=true" 和 "hl.fl= content " 。

"hl=true" 是开启高亮,"hl.fl= content " 是告诉solr 对 name 字段进行高亮(如果你想对多个字段进行高亮,可以继续添加字段,字段间用逗号隔开,如 "hl.fl=name,name2,name3")。 高亮内容与关键匹配的地方,默认将会被 "<em>" 和 "</em>" 包围。还可以使用hl.simple.pre" 和 "hl.simple.post"参数设置前后标签.

查询结果如下:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <response>
  3. <lst name="responseHeader">
  4. <int name="status">
  5. 0
  6. </int>
  7. <int name="QTime">
  8. 2
  9. </int>
10-06 18:57