2012年1月4日
前一篇文章介绍了如何定义Solr的Schema,有了数据的结构定义,下来我们就来看看如何写入数据吧。 将文档数据写入到Solr有很多种方式, 你可以使用xml文档,json文档,csv文档,对于这三种方式,你可以在Linux下使用curl方便的导入数据,比如使用xml文档,你可以这样写:
添加xml文档
curl http://localhost:8983/solr/update?commit=true -H "Content-Type: text/xml" --data-binary '<add><doc><field name="id">testdoc</field></doc></add>'
添加json文档
curl http://localhost:8983/solr/update/json -H 'Content-type:application/json' -d ' [ {"id" : "TestDoc1", "title" : "test1"}, {"id" : "TestDoc2", "title" : "another test"} ]'
当然,你还可以使用DIH(DataImportHandler,这是Solr的一个处理器,用来从其他的异构系统批量导入数据)。
在windows下如果想要导入文件,可以使用文档例子目录下(example\exampledocs)的Post.jar程序来导入文档,在我们搭建好Solr的环境以后,系统里面还没有任何的文档数据,现在我们就试着使用post.jar程序来导入文档,你可以使用命令行(cmd程序),进入到solr的文档例子目录 (example\exampledocs ),然后输入 java -jar post.jar *.xml ,输入完成后回车,数据就导入到了Solr中。现在我们就可以通过Solr的statistics页面来查看是否已经导入数据,如下图:
从图中看到,我们已经导入了17个文档。如果你想查看导入的文档的内容,可以在Solr Admin首页(http://localhost:8983/solr/admin/)的Qeury string中输入"*:*",然后点击Search按钮,你就可以看到我们刚刚导入到系统中的前10个文档的内容。
上面介绍了几种文档的导入方法,DIH相对比较复杂一点,我们后边专门来讲,除此以外的几种方法,如果测试功能时用一下还好,如果正式的生产环境不可能这样的来做,这时我们就需要一些功能强大一些的客户端,方便我们将Solr的功能引入自己的系统。我们可以访问http://wiki.apache.org/solr/IntegratingSolr这个页面,这个页面上列出来各种应用程序环境中可以使用的客户端,比如Java应用程序可以使用SolrJ,Python可以使用SolrPython,Javascript 可以使用 ajax Solr,而对于.net而言,我个人觉得Solrnet是个不错的选择,后续的文章我也会选择使用Solrnet作为演示用的客户端。下一篇文章我会专门讲一下Solrnet的使用。
2011年12月12日
上一篇文章介绍了Solr的管理界面,使用这个管理界面我们我们可以方便的了解现在Solr的运行情况,也可以查看目前的系统是如何配置的,你甚至可以通过它做一些测试和调试,但是也仅止于此,系统的配置你还必须通过各种各样的配置文件。要使Solr可以处理我们自己的文档,第一步要做的就是配置Schema。
Schema是Solr业务逻辑的核心,一个文档包含哪些字段,字段是否被索引,如何索引,如何被查询都在Schema中定义。我们可以在Solr的conf目录下找到schema.xml这个文件,这个文件中就是Schema的定义。需要注意的是一个Solr的实例只能有一个Schema。Schema的定义很像是数据库中的一张表,你在表里面定义字段,比如text字段,数据类型是nvarchar这样。不同的是,在数据库里面,你只能使用系统预设的字段类型来定义字段,而在Solr的schema中你不但可以定义字段,而且还可以定义自己的字段类型,并且定义字段类型往往是最重要的。
我们可以浏览一下这个schema文件,在<types>节点中的所以内容都是字段定义,这些字段类型一块一块的被定义,在每一块的上边有很详细的定义。对于每行一个定义这样的简单字段类型基本上是Solr的基本数据类型,一般来说你不需要去修改它,这些字段的omitNorms attribute都是true,也就是说他们不会被用来分析,只用来存储数据。如果想要更快的范围查询,请考虑使用t前缀的字段类型。我们来看看下面的一段字段定义的配置:
<fieldType name="text_general" class="solr.TextField" positionIncrementGap="100">
<analyzer type="index">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" enablePositionIncrements="true" />
<!-- in this example, we will only use synonyms at query time
<filter class="solr.SynonymFilterFactory" synonyms="index_synonyms.txt" ignoreCase="true" expand="false"/>
-->
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
<analyzer type="query">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" enablePositionIncrements="true" />
<filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
</fieldType>
需要分析的字段类型一般是这样的,name指定了字段类型的名称,就像是数据库的nvarchar这样的名字一样。class指明这个类型对应的是什么的java数据类型,在字段定义中你可以定义分析器,分析器有两种,索引分析器和查询分析器,对于每个字段类型,你只能指定一个查询分析器和一个索引分析器。分析用来对字段的内容进行分词,过滤,转换等等,我们可以看到在分析器的节点内定义了一系列的处理步骤,这些步骤是有序的。从分析器的类型也就可以直观的了解到,索引分析器用于建立索引时,查询索引器用于查询时。如果字段类型仅指定了一个分析器,并且没有指定类型,说明索引和查询都使用这个分析器。
有了字段类型,我们就可以定义需要处理的文档的所具有的字段了。我们可以看到,在schema文件中本身已经定义了很多的字段,它们都位于<fields>节点内。这些字段是为例子数据文档准备的,如果你需要的处理文档足够简单并且本身是英文的,那么你甚至都不需要修改Schema文件,直接利用这些字段就可以了。当然只是偷懒的做法,如果用于练习是足够了,如果用于生产环境,还是把不需要的字段删掉吧。删除的时候注意,不要把dynamicField的内容删掉了,这些dynamicField是又特殊含义的,他们的名字都像name="*_i"一样有个"*_"的前缀。如果你不想在schema中定义这个字段又想存贮这个字段的值,那么在向Solr传地文档内容的时候,把字段名名为"_i"后缀,那么字段的值就会按<dynamicField name="*_i" type="int" indexed="true" stored="true"/>定义的动态字段的属性来存储,同样的道理,查询也是一样的。在字段定义时,你可以指定几个attribute,那么当时是指字段的名字,type指定的是字段的类型,字段的类型当然指的就是前面定义的类型,这个类型决定了该字段的内容如何被索引和查询,indexed是个布尔值,指示该字段是否被索引,stored指示该字段的内容是否被存储,如果你的查询只是返回是否命中,并不返回字段的内容或者高亮内容中的某些部分的,可以将该属性的值设定为false,multiValued指示该字段是否存储多个值。
defaultSearchField用来指定,如果查询时没有指定字段名称时查询哪个字段的索引值。
solrQueryParser 指示如果查询中包含了两个term,并且没有指定逻辑运算符的时候我们默认用什么逻辑运算符,一般来说我们都会默认是OR。
上边就Schema的定义了, 后边我写Solr处理中文文档的时候,会稍微详细的再介绍一下这个部分,如果你处理的只是英文文档的话,类型基本不用修改了,只用定义自己需要的字段就可以了。
2011年12月8日
昨天这个系列开篇了,今天就趁热打铁吧。有一点要注意的是,一开始我是在64位的Windows 7上的Tomcat中部署Solr的,在使用过程中发现非常的不稳定,经常添加两个文档或者是查询一两次后,tomcat就崩溃了,让我对Solr的稳定性很是担忧,又来部署到虚拟机中的CentOS上,非常的稳定又高效。在Windows 7上为什么不稳定,我没有去分析,可能是因为各个组件的版本间的问题吧。如果哪位同学希望在Tomcat中部署Solr,请参考《Solr with Apache Tomcat》或者《在tomcat上部署solr 》。如果使用Tomcat,一定不要忘记在server.xml文件中connector节点中添加URIEncoding="UTF-8",否则你在做中文检索的时候就会出问题。
现在环境已经搭建了好,我们通过http://localhost:8983/slor/admin地址来访问Solr的管理页面,如下:

简要的介绍一下这个管理界面吧,首先是Schema,点击这个链接可以看到Solr的conf目录下的schema.xml文件的内容,从这里看到的内容和从Schema Browser链接里看到的内容是一致的,只是形式不同,SCHEMA BROWSER看到的更友好一些,儿SCHEMA里看到的就是原本的schema.xml的文本。在这两个地方你都不能修改里面的内容。Schema文件定义了Solr里面存储的文档的字段类型以及字段,这个我们后边会详细讲。
ANALYSIS这个链接是用来帮助你开发和调试的,如下图:

在这里你可以很方便的测试你定义的字段类型以及字段是否正确,你指定字段,然后在Field Value(Index)中放入你期望分析的文档内容,在Field Value(query)中放入你期望检索的词,点即Analyze按钮,下边就会出现文档是如何进行分词的,然后你检索的词命中的话就会高亮显示。这个工具对于我们进行字段定义,配置是很有用的。
STATISTICS,顾名思义就是统计信息,在这里你可以看到在Solr里面索引了多少文档,各种Handler的处理情况,比如搜索处理器,每秒钟处理多少个响应,每个响应使用了多长时间,还有Cache的使用情况,比如林林种种的Cache是如何设置的,Cache的命中率如何,命中次数如何,自热的次数以及自热的用时等等,这些信息对日后的性能调校是又很大的用处的。
INFO的用处不太大,从这里面你可以看到Solr内部的这个种Handler是如何配置的。
Distribution 是用来查看Solr的分布式设置的,从这里你可以看到当前的Solr实例是Master Server还是Slave Server,系统是如何分布的。分布式正是Solr的强大之处,利用这些特性你可以很方便的Scale up或者Scale out你的系统。
在LOGGING里,你可以设定哪些日志是需要输出的。
最后介绍一下管理界面中的一个重要的组成部分,就是Make a Query,如果你仅仅只是想看看现在solr里面是否能检索到某个词,就可以直接在这里输入,然后查看结果,比如输入“text:lucene”,就是查询在text字段的内容中包含lucene这个单词的文档。这里能使用的功能十分有限,相当于仅仅只发送给Solr了q参数的内容。如果你想使用更复杂的查询,那么点击Make a Query 右边的FULL INTERFACE,会出现下边的界面:

不要被这个FULL INTERFACE给忽悠了,以为这就是Solr全部的查询功能,其实,除了debug参数,这里面不过依次列出了q,fq,start,rows,fl,qt,hl,hl.fl参数,二实际上lucene/Solr提供的的查询参数是数倍于这些。所以这个应付简单的查询还可以,复杂的查询,可以通过查询结果的地址栏手动修改吧,如下图:

好了,天色已晚,今天就写到这里吧,接下来讲解schema的定义
2011年12月7日
换了个工作单位,也就换了从事的项目的业务类型。新的项目中要需要使用全文检索功能,由于项目是基于SQL server的应用,所以旧的设计也就使用了SQL server的Full-text Search Engine来实现全文检索功能。在使用SQL server 的全文检索功能的过程中,发现有很多的问题不能很好的解决,比如Cache,一般来说,对于SQL server的缓存也就是执行计划的缓存和查询结果的页面缓存,远远不够,而且也很难根据自己的业务需要去调整缓存的参数。另外对于多语言的分词算法问题,SQL server虽然内置了50多种语言的支持,但是都不够完美,如果自己想要进行替换,应该是很困难的。还不支持Highlighting,还有现在应用很广泛的Faceting以及Field Collapsing。客户推荐我们使用一下Solr来改进全文检索功能,所以我就花了些时间来研究了下Solr,并打算写一些文章总结一下Solr的使用,也希望对各位同学有帮助吧。
唧唧歪歪说了一堆,现在就进入正题吧 。
首先介绍一下Solr是什么。要说Solr,先说说Lucene。Lucene是Apache基金会一个全文检索库类库的项目,这个项目的开源的,这个类库是使用Java开发的,功能非常强大,如果大家感兴趣可以去看看http://lucene.apache.org/.当然这个类库也有几个其它语言的实现,比如Python,也有.net的叫做lucene.net,不过因为社区活跃度不高,Apache基金会已经不再赞助这个子项目了。 如果哪位同学希望把全文检索的功能集成在自己的系统里面,或者扩展luence的全文检索功能,那应该好好学学Lucene。如果你只想使用全文检索,对底层的算法和逻辑既不想研究也不想干预,那么Solr可能是一个更好的选择。简单的说,Solr就是使用Lucene库实现的一个http服务,当然他也做了很多的扩展。你可以将Solr部署在任何一个Java Serverlet容器里,比如Tomcat,Jetty。你可以通过RESTful的url就可以和Solr进行通信,进行文档的indexing和检索。这样一来,易用性就得到大大的提升,因为不管你的项目是基于什么操作系统平台的,使用什么语言开发的,只要你能和http服务器进行通信,就能非常简单快捷的在你的项目中实现全文检索功能。如果要更加详细的谅解Solr的相关信息,请访问:http://lucene.apache.org/solr/
接下来我们需要下载和部署Solr。从 http://mirror.bjtu.edu.cn/apache//lucene/solr/这个页面里选择下载最新的版本,目前是3.5.0,刚刚出炉的。在安装前有几个准备工作要做。Solr是用Java实现的,所以毫无疑问Java的虚拟机是要的,不管你是在Window上安装,还是在Linux上安装,点击这里下载JDK,安装完JDK别忘了检查JAVA_HOME环境变量是否设置了。另外,如果你打算使用Tomcat的话,那就得先安装Tomcat,点击这里了下载。其实在实践和练习的时候是用Jetty是比较方便的。如果你在windows上使用Solr,那么把刚才下载的Solr文件包加开,使用dos 命令行控制台进入example目录,输入java -jar start.jar,然后回车,如果没有什么异常信息,Solr就启动起来了。现在你打开浏览器,输入http://localhost:8983/solr/admin/,就可以进入Solr的管理控制台了,如下图

简单的安装已经完成,可以进行文档索引和查询了。
今天的开篇就到这里吧,算是准备了一个环境。后续我会写一系列文章来介绍Solr的使用。
在提供一些对大家准备环境有帮助的信息:
Solr client for .Net --google code上的项目,项目的负责人很积极,如果你提交了Issue或者Defect,他会持续的关注和反馈。
2008年3月5日
Blog荒废很久了,算算看差不多有10个月没有在园子里写文章了。去年真的太忙了,好几个项目需要同时上线,所以很多朋友的提问都没有来得及回复,给大家说声抱歉。
最近琢磨着应该写一些新东西了。从大家的留言来看,大家还是对控件的开发很感兴趣的,我打算做一个图像的显示和编辑控件,演示一些控件制作中细节技术。
2007年5月14日
摘要: 我在前一篇文章里提到,对于停靠工具栏或者是视图最好是不要将实例放到词典中,而是将工具栏或者视图的类型放到词典中,因为视图类型会经常的被重用,并且会经常被关闭或者再打开。当实例被关闭后,资源就被释放了,对于实例的管理就会比较麻烦,所以我们分为两步走。在插件被加载的时候,我们只注册类型,在应用程序运行的时候,我们通过某种途径来实例化他。 我修改的以前的例子,主要突出本次演示的功能。这次的例...
阅读全文
2007年5月11日
摘要: 最近真的真的太忙了,以至于一个多月都没哟更新我的blog。昨天晚上,一个网上的朋友看了我的ToolBox的文章,问我一个问题,他说如何让ToolBox控件也能响应键盘操作,也就是用Up,down按键来选择工具箱控件里的Item,他添加了键盘事件,但是不起作用。一开始做这个控件的时候也只是演示一下控件的制作过程,只用了很短的时间做了一个,只考虑了用鼠标选取,没有考虑键盘操作,我想要添加键盘操作无非重...
阅读全文
2007年3月26日
摘要: 既然做好了框架,我们就希望为某个目标服务,我们要提供一些基本的服务,方便用户继续扩展他的功能。首先想到的功能就是,菜单,工具栏的管理,接下来我们要实现一些更流行的功能,比如停靠工具栏等等。 如何实现这些服务呢?我们希望我们的插件在运行时可以获得应用程序本身的菜单,工具条,停靠工具栏等等,然后向他们添加项目,比如加入一个菜单项,添加一个工具栏按钮。为了在运行时获得某个菜单或者工具栏,我们要为每一个菜...
阅读全文
2007年3月14日
摘要: 前天发了构建插件式的应用程序框架(五)----管理插件这篇文章,有几个朋友在回复中希望了解插件之间是如何通讯的。这个系列的文章写到这里,也该谈谈这个问题了,毕竟已经有了插件管理。不知道大家有没有注意到我在第四篇文章里谈到的服务容器(Service Container),Service是我所提到的插件式的应用程序框架的基础,我们也可以回头看看IApplication的接口定义,IApplicatio...
阅读全文
摘要: 构建插件式的应用程序框架(一)----开篇 构建插件式的应用程序框架(二)----订立契约 构建插件式的应用程序框架(三)----动态加载 构建插件式的应用程序框架(四)----服务容器 构建插件式的应用程序框架(五)----管理插件 构建插件式的应用程序框架(六)----通讯机制构建插件式的应用程序框架(七)----基本服务构建插件式的应用程序框架(八)----视图服务的简单实现
阅读全文