在结果中返回函数值

假设你有一个服务,你的用户可以搜索不同的公司,用户输入一个简单的关键字,可以返回匹配关键字的公司,但是有一天,用户要求返回的公司列表中可以显示公司跟用户的距离,这是该怎么做呢?

准备工作

在开始之前,需要先了解字段别名功能,具体可以参看这里

怎么做

1.假设我们在 schema.xml 中定义了如下索引结构:


<field name="id" type="string" indexed="true" stored="true"
required="true" multiValued="false" />
<field name="name" type="text" indexed="true" stored="true"/>
<field name="loc" type="location" indexed="true" stored="true"/>
<dynamicField name="*_coordinate" type="double" indexed="true"
stored="false" />

2.我们需要定义 location 字段类型,如下所示:


<fieldType name="location" class="solr.LatLonType"
subFieldSuffix="_coordinate"/>

3.再假设我们有以下索引数据


<add>
<doc>
<field name="id">1</field>
<field name="name">Company 1</field>
<field name="loc">56.4,40.2</field>
</doc>
<doc>
<field name="id">2</field>
<field name="name">Company 2</field>
<field name="loc">50.1,48.9</field>
</doc>

<doc>
<field name="id">3</field>
<field name="name">Company 3</field>
<field name="loc">23.18,39.1</field>
</doc>
</add>

4.现在可以通过以下语句查询到名称中匹配 company  的公司

q=name:company&fl=*

5.假设我们已经获得了客户端位置是 50.0, 28.0,然后我们打算在公司结果列表中显示客户端跟这些公司的距离。这时我们需要将以下参数加载 fl 中:

dist:geodist(loc,50.0,28.0)

这样整个查询看起来像这样:

q=name:company&fl=*,dist:geodist(loc,50.0,28.0)

查询返回的内容如下所示:


<?xml version="1.0" encoding="UTF-8"?>
<response>
<lst name="responseHeader">
<int name="status">0</int>
<int name="QTime">0</int>
<lst name="params">
<str name="q">name:company</str>
<str name="fl">*,dist:geodist(loc,50.0,28.0)</str>
</lst>
</lst>
<result name="response" numFound="3" start="0">
<doc>
<str name="id">1</str>
<str name="name">Company 1</str>
<str name="loc">56.4,40.2</str>
<double name="dist">1077.4200268973314</double>
</doc>
<doc>
<str name="id">2</str>
<str name="name">Company 2</str>
<str name="loc">50.1,48.9</str>
<double name="dist">1487.4260767512278</double>
</doc>
Chapter 4
153
<doc>
<str name="id">3</str>
<str name="name">Company 3</str>
<str name="loc">23.18,39.1</str>
<double name="dist">3134.746384852772</double>
</doc>
</result>
</response>

上面结果中 dist 就是客户要的距离字段。

solr 4.x 特性:局部更新索引

该功能在 lucene4.x 的更新日志中有提到,最近终于找到了相关的说明,详见更新文档的单个字段。该功能看起来相当不错,假设要索引文章的新闻,新闻有个点击数的字段,需要搜索的结果按点击数排序时,这样 就能把点击数也写进索引库,单点击数变化时,单独更新点击数即可,此前是需要重现更新整个索引的,包括文章内容、标题等。这个说明中只提到了用 curl 方式类更新,理论上在 solrj 中也会有相关的接口。另外从描述中看,它只提到了,不需要送其他字段的值,不知道是否 solr 内部将其他字段读取出来,然后再自行索引进去,如果是这样的,整个性能就不济了,只是方便用户少送几个字段。具体情况需要测试一下或者跟踪一下源码

Apache Nutch 1.6 发布

Apache Nutch 1.6 发布,该版本修复了超过 20 个 bug,新功能包括:新的 HostNormalizer,可通过 MIME-type 和 Indexer API 的功能增强来动态设置 fetchInterval ,更新 Tika 到 1.2 版本,更新 Autimaton 到 1.11-8 版本。

Solr In action 试读本

《solr in action》这个可能是第一本关于 Solr 4.0 的书籍,看样子是还没写完,这里有第一章的文件,有兴趣的同学可以点击下载:Solr_meap_ch01

文件大小:1.44M

格式:PDF

页数:26页

 

 

带 IK 分词器的 Luke

 

 

Luke 之前的文章中有介绍过,这次提供一个带IK分词器的luke,点击这里下载。该版本是在 luke 3.5 基础上加入了 IK2012 的包,可以对solr3.5(lucene3.5)、solr3.6(lucene3.6)的词库进行查看。

这样,在 luke 的 plugins 界面中,可以下拉选择到IK 的分词器,输入相应的文本,就能查看到分词的结果。如下图所示:
luke&IK在 search 界面里,也可以调出 IK 分词器对关键字进行分词,然后测试搜索结果。如下所示:

 

Solr 缓存配置(一)

缓存在 Solr 中充当了一个非常重要的角色,Solr 中主要有这三种缓存:

  • Filter cache(过滤器缓存),用于保存过滤器(fq 参数)和层面搜索的结果
  • Document cache(文档缓存),用于保存 lucene 文档存储的字段
  • Query result(查询缓存),用于保存查询的结果
还有第四种缓存,lucene 内部的缓存,不过该缓存外部无法控制到。
通过这 3 种缓存,可以对 solr 的搜索实例进行调优。调整这些缓存,需要根据索引库中文档的数量,每次查询结果的条数等。
在调整参数前,需要事先得到 solr 示例中的以下信息:
  • 索引中文档的数量
  • 每秒钟搜索的次数
  • 过滤器的数量
  • 一次查询返回最大的文档数量
  • 不同查询和不同排序的个数
这些数量可以在 solr admin 页面的日志模块找到。假设以上的值分别为:
  • 索引中文档的数量:1000000
  • 每秒钟搜索的次数:100
  • 过滤器的数量:200
  • 一次查询返回最大的文档数量:100
  • 不同查询和不同排序的个数:500
然后可以开始修改 solrconfig.xml 中缓存的配置了,第一个是过滤器缓存:
<filterCache class="solr.FastLRUCache" size="200" initialSize="200"  autowarmCount="100"/>

第二个是查询结果缓存:

<queryResultCache class="solr.FastLRUCache" size="500" initialSize="500" autowarmCount="250"/>

第三个是文档缓存:

<documentCache class="solr.FastLRUCache" size="11000" initialSize="11000" />

这几个配置是基于以上的几个假设的值进行调优的。

Apache Solr 3.6.1 发布

改版主要是跟随 Lucene 升级,Lucene 本轮升级主要是 Bug 修改

动态字段

正常情况下,需要事先把知道的字段定义在 schema.xml 中,当有不确定的字段时,这时可以使用动态字段。

这里是一个动态字段定义的示例:
<dynamicField name="*_s" type="string" indexed="true" stored="true"/>
这样,送过来的索引数据中,如果有以 _s 结尾的字段的值都都会被按照上述的索引方式进行索引,如字段名称为title_s,content_s。
在匹配过程,如果动态字段和静态字段都符合,会优先匹配静态字段。另外动态字段的仅支持 * 这一通配符,这个通配符仅能位于开头或结尾。

启用 solr suggest

suggest 是搜索引擎一个方便的功能,对数据的关键字进行预测和建议,减少了用户的输入,大体的效果如下:

suggest幸运的是 solr 也提供了类似的功能,在该功能的基础上,配合 jQuery 或 kissy 的自动完成组件就可以实现类似上面的功能。
启动该功能的过程大体如下:
suggest 的功能依赖拼写组件,solr_home/data 目录下会有一个 spellchecker 目录,该目录用于存放 suggest 和 拼写检查的索引库,所以要先配置 spell 功能,配置如下:
 <searchComponent name="spellcheck" class="solr.SpellCheckComponent">
    <str name="queryAnalyzerFieldType">textSpell</str>
    <lst name="spellchecker">
      <str name="name">default</str>
      <str name="field">title</str>
      <str name="buildOnCommit">true</str>
      <str name="spellcheckIndexDir">spellchecker</str>
    </lst>
  </searchComponent>
上述中的 field 用于指定主索引库中用于 spellchecker 索引的数据从主索引库的那个字段来获取。buildOnCommit 该属性为 true 时,当主索引库有提交指令时,将会自动把指定字段的内容送到 spellchecker  索引库,作为拼写检查和 suggest 使用。
接下来配置 suggest 的处理组件和请求类,如下所示:
<searchComponent class="solr.SpellCheckComponent" name="suggest">
	<lst name="spellchecker">
		<str name="name">suggest</str>
		<str name="classname">org.apache.solr.spelling.suggest.Suggester</str>
		<str name="lookupImpl">org.apache.solr.spelling.suggest.tst.TSTLookupFactory</str>
		<float name="threshold">0.005</float>
		<str name="buildOnCommit">true</str>
	</lst>
</searchComponent>
<requestHandler class="org.apache.solr.handler.component.SearchHandler" name="/suggest">
	<lst name="defaults">
		<str name="spellcheck">true</str>
		<str name="spellcheck.dictionary">suggest</str>
		<str name="spellcheck.onlyMorePopular">true</str>
		<str name="spellcheck.count">5</str>
		<str name="spellcheck.collate">true</str>
	</lst>
	<arr name="components">
		<str>suggest</str>
	</arr>
</requestHandler>
这时候重新提交数据,会发现原先为空的 spellchecker 为空的索引库中有数据了,然后打开类似这样的网址(请将q=的值换成 title 字段中有的值)

http://localhost:8983/solr/suggest/?q=%E7%94%9F

会得到如下结果:
suggestRSS

luke:lucene 索引查看工具

luke 是 lucene 索引查看工具,基于 swing 开发的,是 lucene、solr、nutch 开发过程中不可或缺的工具。在测试搜索过程,进程出现搜不到东西或者搜到的东西不是想要的结果时,这时就需要用 luke 查看一下索引库的情况,来协助排查问题。
下载:
luke 可以从 google code 上下载
只是为了使用 luke 的话,下载 jar 包即可,经常有朋友下载成了源码包,最后不知道如何运行,从 luke 在 1.0 版版本对应的是 lucene 3.0,1.0 以前的版本,如0.9,对应的 lucene 版本为 2.9,从 1.0 以后,luke 跟 lucene 的版本号一一对应了,暂时没有找到3.6版本的luke,其实可以用4.0的luke代替,可以兼容的。
假设下载了lukeall-3.5.0.jar ,然后右键点击这个 jar,打开方式中选择 java 来运行他,即可看如下运行界面:
luke
在path中写入索引库的目录,点击OK即可打开索引库。
打开索引库后可进行的操作就相对简单了,大家自行探索了,有问题 QQ 群内询问。

Copyright © All Rights Reserved · Green Hope Theme by Sivan & schiy · Proudly powered by WordPress