转载:Solr的自动完成实现方式(第一部分:facet方式)
转自:http://www.cnblogs.com/ibook360/archive/2011/11/30/2269059.html
大部分人已经见过自动完成(autocomplete)的功能了(见下图),solr提供了构建这个功能的机制。今天,我将给你展示如何使用facet的方式来添加自动完成机制。
索引
设想你想在你的在线商店中,给用户一些提示,比如商品的名称。假设我们的索引构建如下:
<field name="id" type="string" indexed="true" stored="true" multiValued="false" required="true"/>
<field name="name" type="text" indexed="true" stored="true" multiValued="false" />
<field name="description" type="text" indexed="true" stored="true" multiValued="false" />
text类型的定义为:

<fieldType name="text" class="solr.TextField" positionIncrementGap="100">
<analyzer>
<tokenizer class="solr.WhitespaceTokenizerFactory"/>
<filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="1" catenateNumbers="1" catenateAll="0" splitOnCaseChange="1"/>
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
</fieldType>

配置
开始前,首先考虑你要实现的功能:是要实现一个名字的提示,还是全名的提示。这都依赖于我们的选择,我们必须为需要引导的地方设置适当的域。
单词提示
在单词的情况下,我们使用的域也即一个token。在这种情况下,域名为name就足够了。但是,这属于一个词干,analysis的操作都在词干上,因此,我们最好换一个其他的类型。
全名提示
我们使用一个不同的域配置来定义全名提示--最好一个未被定义的域。但是我们不能使用基于类似string这种类型的域,基于这个原因,我们定义为一下的域:
<field name="name_auto" type="text_auto" indexed="true" stored="true" multiValued="false" />
text_auto类型的定义为:
<fieldType name="text_auto" class="solr.TextField">
<analyzer>
<tokenizer class="solr.KeywordTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
</fieldType>
为了不影响原有数据的格式,将原数据进行拷贝:
<copyField source="name" dest="name_auto" />
如何使用
为了使用这个数据,我们准备了一个简单的查询语句:
q=*:*&facet=true&facet.field=FIELD&facet.mincount=1&facet.prefix=USER_QUERY
需要替换的地方:
FIELD:我们打算提供建议的域,在本例中域名为name 或name_auto
USER_QUERY:用户输入的字符
这里可以设置rows=0,这样可以只返回facet的结果,而没有查询结果。当然这不是必须的。
查询的一个例子可以这样写:
fl=id,name&rows=0&q=*:*&facet=true&facet.field=name_auto&facet.mincount=1&facet.prefix=har
查询结果会返回这样的结果:

<response>
<lst name="responseHeader">
<int name="status">0</int>
<int name="QTime">0</int>
</lst>
<result name="response" numFound="4" start="0"/>
<lst name="facet_counts">
<lst name="facet_queries"/>
<lst name="facet_fields">
<lst name="name_auto">
<int name="hard disk">1</int>
<int name="hard disk samsung">1</int>
<int name="hard disk seagate">1</int>
<int name="hard disk toshiba">1</int>
</lst>
</lst>
<lst name="facet_dates"/></lst>
</response>

扩展功能
这里说一下他的一些常用的功能。
第一个是显示用户的一些额外的信息,比如当你选择某个提示词时,显示的结果的数量。这是一个很有意思的特性。
另一个是使用facet.sort参数进行排序。这依赖于你的需求,我们可以按文档的数量排序(默认方式,设参数为true即可),或者按字母序排序(设为false)。
我们也可以通过设置facet.mincount来显示比指定的数量更多的提示词。
另外一个很好的特性是提示词不仅可以通过用户的类型获取,还可以通过其他的属性获取,这类似于类别。举个例子,我们想给用户展示家庭用品相关的商品,我们假设现在用户对DVD类型的商品并不感兴趣,这样我们添加一个参数: fq=department:homeApplications(假设有这个department)。通过这样的一个查询,你就不需要在所有的索引中匹配了,而是在我们选择的department里选择。
结尾
跟其他方法一样,它有优点,也有缺点。优点就是易于使用、没有额外的组件依赖,并且能将结果约束在一个很小的范围内来更好的匹配用户的需求;另外一个很大的优点是它对每个提示词都附带了结果的统计。缺点就是需要添加额外的类型和字段;另外由于其facet的机制,对机器性能和load都非常消耗。
PS:我自己测试了一下,由于这个功能是实时请求的(每个字母的输入都是一次请求),如果量很大的时候,统计数量会占用很大的内存,内存过小(我的2G)很容易OOM。所以,这个功能慎用。
网上有个哥们建议使用facet.prefix,由于目前没有这方面的强烈需求,故在此搁下,需要时再从这里起步。
原文:http://java.dzone.com/news/solr-and-autocomplete-part-1
转载:Solr的自动完成实现方式(第一部分:facet方式)的更多相关文章
- 转载:Solr的自动完成实现方式(第二部分:Suggester方式)
转自:http://www.cnblogs.com/ibook360/archive/2011/11/30/2269077.html 在Solr的自动完成/自动补充实现介绍(第一部分) 中我介绍了怎么 ...
- 【转载】 Java中String类型的两种创建方式
本文转载自 https://www.cnblogs.com/fguozhu/articles/2661055.html Java中String是一个特殊的包装类数据有两种创建形式: String s ...
- Spring学习笔记之 Spring IOC容器(二) 之注入参数值,自动组件扫描方式,控制Bean实例化方式,使用注解方式
本节主要内容: 1. 给MessageBean注入参数值 2. 测试Spring自动组件扫描方式 3. 如何控制ExampleBean实例化方式 4. 使用注解方式重构Jdb ...
- Android的Fragment的第一种声明方式
Android的Frangment的第一种声明方式 实际效果图如下: 项目结构图如下: fragment1: package com.demo.fragementfirst; import andro ...
- 用POI导出excel时,较长的数字不想被自动变为科学计数法的解决方式(转)
做过很多次导出excel了.都碰到一个问题,内容里如果包含一个比较长的数字,比如订单号“2546541656596”,excel会自动变成科学计数法... 弄过好几次都没有解决,最近又要导出excel ...
- 使用Typescript重构axios(二十)——请求取消功能:实现第一种使用方式
0. 系列文章 1.使用Typescript重构axios(一)--写在最前面 2.使用Typescript重构axios(二)--项目起手,跑通流程 3.使用Typescript重构axios(三) ...
- LoadRunner 脚本学习 -- 动态储存方式和静态储存方式
我们在定义变量是,根据定义的位置不同,分为全局变量与局部变量.我出生在一个叫“舞阳”的小县城,在这个县城中也有人名“舞阳”,前一个作用于整个县城,后一个只作用于他个人.那么从变量值的存在生存期角度,又 ...
- 1.tomcat部署项目的几种方式和weblogic部署方式及一点通讯
第一种部署方式: 直接使用myeclipse 找到server服务 添加要部署的项目Add Deployment ,然后选中某个项目,首选Exploded Archive(development ...
- spring 四种依赖注入方式以及注解注入方式
平常的java开发中,程序员在某个类中需要依赖其它类的方法,则通常是new一个依赖类再调用类实例的方法,这种开发存在的问题是new的类实例不好统一管理,spring提出了依赖注入的思想,即依赖类不由程 ...
- Python小白学习之路(九)—【字符串格式化】【百分号方式】【format方式】
写在前面: 最近的事情好像有很多.李咏的离去,让我觉得很突然,仿佛印象中就是主持节目的他,看着他和哈文的爱情,很是感动.离去,没有什么抱怨,只是遗憾. 总会感慨,时光的流逝. 好像真的很快,转眼间,我 ...
随机推荐
- 一次完整的HTTP请求流程
HTTP通信机制是在一次完整的HTTP通信过程中,Web浏览器与Web服务器之间将完成下列7个步骤: 1. 建立TCP连接: 在HTTP工作开始之前,Web浏览器首先要通过网络与Web服务器建立连接, ...
- SVN版本问题:svn: E155021: This client is too old to work with the working copy at
最近Android Studio SVN老是提示: SVN版本问题:svn: E155021: This client is too old to work with the working copy ...
- [转] 主流JS框架中DOMReady事件的实现
在实际应用中,我们经常会遇到这样的场景,当页面加载完成后去做一些事情:绑定事件.DOM操作某些结点等.原来比较常用的是window的onload 事件,而该事件的实际效果是:当页面解析/DOM树建立完 ...
- (转)C#调用默认浏览器打开网页的几种方法
转载,原文地址:http://blog.csdn.net/testcs_dn/article/details/42246969 CSharp调用默认浏览器打开网页的几种方法 示例界面: 方法一:从注册 ...
- 去除angularjs路由的显眼的#号
在接触到angularj并完成第一个demo后,惊奇地发现居然还可以这样开发前端界面.个人喜欢的一个功能点就是ng的路由功能,可以很好地将视图放入多个文件中.但最基础的使用会给url添加一个显眼的#, ...
- ABP的第一个程序和遇到的一些问题
ABP在这里就不多介绍了.在这篇文章中主要介绍使用模板生成的ABP项目使用遇到的一些问题. 1.首先在http://www.aspnetboilerplate.com/ 官方网站上创建一个模板项目, ...
- sql install error
解决SQL Server 2008 R2安装过程中提示Could not open key的解决方法:以管理员身份运行CMD命令提示符,输入以下语句并运行就OK了secedit /configure ...
- Nancy+BUI+SQLite自动更新服务端和客户端保护更新程序
写了一个自动更新服务网站和自动更新客户端.基本功能测试完毕.记录下 项目地址:https://github.com/TeemoHQ/AutoUpdate 需求 自动集成,回退版本,守护进程,服务端操作 ...
- Objective - C 值对象 NSNumber和NSValue
在进行数据处理的时候,因为对象类型的不同, 并不能进行相应的数据处理,所以必须要进行数据类型的转换,这也就是NSNumber,NSValue这两类值对象出现的原因. 简而言之,NSNumber就是实现 ...
- Mac Aria2 使用Privoxy将socks代理转化为http代理
安装Privoxy 打开终端安装privoxy来实现这里我是通过brew来进行的安装 brew install privoxy 看到这行已经安装成功 ==> Caveats To have la ...