Solr快速入门教程

一、概述

本文涵盖了如何安装和运行Solr,如何将各种数据源导入多个集合(Collection)之中,以及体验Solr的管理和搜索界面。

二、系统需求

若要深入学习本教程,你将需要满足以下条件:

  1. 需要满足系统需求[1]
  2. 使用合适的Solr发行版本。本教程是基于Apache Solr 5.3.1版本编写的。

本教程使用的完整环境信息如下所示:

  1. CPU:单核-1.70GHz
  2. 内存:2GB
  3. IP地址:192.168.21.129
  4. 操作系统:CentOS 6.6 x86_64
  5. JDK版本:1.8.0_51(64位)
  6. Solr版本:5.3.1

三、入门

请在运行Solr服务器的同一台机器上运行浏览器,因此,当你点击本教程中的链接时,就能直接在浏览器上正确地打开这些链接。

首先,请解压缩安装Solr的发行版本,然后将你的工作目录切换至Solr的安装目录中,本文将Solr安装在/usr/local/solr-5.3.1目录。注意,Solr基础目录的名称可能会有不同,因为目录名可能会包含Solr的版本号。本文通过以下Shell命令安装Solr:

  1. cd /root/Downloads
  2. wget http://apache.fayea.com/lucene/solr/5.3.1/solr-5.3.1.tgz
  3. tar xvzf solr-5.3.1.tgz
  4. mv solr-5.3.1 /usr/local/
  5. cd /usr/local/solr-5.3.1

若要启动Solr,则在Shell中运行以下命令即可:

  1. bin/solr start -e cloud -noprompt

若Solr启动成功,则Shell会返回如下信息:

启动SolrCloud

如果你在Web浏览器中能够打开Solr管理界面,那么你就能看到Solr正在运行,Solr管理界面的URL为:http://192.168.21.129:8983/solr/。这个页面是管理Solr的主要入口点。

现在,Solr将会运行两个“节点”,一个在7574端口上运行,另一个在8983端口上运行。Solr会自动创建一个集合,名为“gettingstarted”,这个集合包含两个分片(Shard),每个分片都有两个复制。管理界面中的Cloud标签页很好地图示了这个集合:

SolrCloud结构

四、索引数据

你的Solr服务器现在已经启动运行了,但是它并不包含任何数据。安装Solr时也会安装bin/post工具,这样从一开始就能很方便地将各种类型的文档(Document)导入Solr之中。接下来,我们将会使用这个工具索引示例数据。

你需要在命令行中运行这些示例,并且必须要在Solr的安装目录中。你用来启动Solr的命令行就可以满足这个要求。

  • 注意:目前,bin/post工具并没有相应的Windows脚本,但是你可以调用底层的Java程序。请参考Windows平台发布工具的相关文档[2]

1. 索引“富文本”文件目录

首先,我们可以索引本地的“富文本”文件,包括HTML、PDF、微软的Office格式(例如MS Word)、纯文本,以及很多其他格式。bin/post工具能够爬取某个目录中的文件,甚至可以递归地去爬取文件,然后将每个文件的原始内容发送给Solr,最后Solr会提取和索引这些数据。安装Solr时也会安装一个docs/子目录,这个目录中的大部分文件是HTML文件,我们可以很方便地为这些内建文件建立索引。在Shell中运行以下命令,索引docs/目录:

  1. bin/post -c gettingstarted docs/

在Shell中运行上述命令之后,输出信息如下所示:

发布docs目录中的文档

这个命令可以按照如下分解:

  • -c gettingstarted:存储索引数据的集合的名称

  • docs/:安装Solr的docs/目录的相对路径

现在,你已经为数千个文档建立了索引,并且将索引数据存储在Solr的gettingstarted集合之中,然后提交了这些修改。在浏览器中打开Solr管理界面的Query标签页,你就可以搜索“solr”关键字了,在q参数框中输入“solr”(替换默认的“:”,这表示匹配所有的文档),然后点击“Execute Query”按钮。请参考下文的“搜索数据”章节,了解更详细的信息。

为了索引你自己的数据,请重新运行目录索引命令,这个命令需要指向你自己的文档目录。例如,在Mac系统中,你可以尝试用~/Documents/目录或~/Desktop/目录来替换docs/目录。你可能想要从一个干净的环境开始尝试,那么就需要再次清空系统,而不是将你自己的内容和Solr的docs/目录的内容存储在一起,请参考下文的“环境清理”章节。

2. 索引Solr的XML文件

Solr可以为各种输入格式的结构化数据建立索引。在历史上,将格式化内容导入Solr的主要格式就是Solr的XML格式[3]。很多的Solr索引器都可以将域内容转换为Solr的XML输出,通常支持直接提交的HTTP请求至Solr的/update端点。

Solr支持示例数据中的几种Solr XML格式的文件。注意:示例中的科技产品的数据含有更加特定于域的配置,包括数据模式和浏览器界面。如果你想要bin/solr脚本提供对这种数据的内建支持,那么你可以运行bin/solr start -e techproducts命令,这个命令不仅仅会启动Solr,而且还会为这些数据创建索引(在运行这个命令之前,请务必先运行bin/solr stop -all命令)。然而,下面的示例假定使用bin/solr start -e cloud命令来启动Solr,这样才能和本文中的所有示例保持一致,因此,示例使用的集合是“gettingstarted”,而不是“techproducts”。

使用bin/post脚本,为示例的Solr XML文件创建索引,这些文件在xample/exampledocs/目录中:

  1. bin/post -c gettingstarted example/exampledocs/*.xml

运行上述命令之后,你可以在Shell中看到如下输出:

导出exampledocs目录

现在,你可以使用默认的Solr查询语法来(它是Lucene查询语法的超集)搜索所有类型的数据了。

注意:你可以通过以下页面浏览被索引的文档:http://192.168.21.129:8983/solr/gettingstarted/browse/browse页面使得你能够体验Solr的技术能力,Solr提供了一个常见的、有些粗糙的交互式HTML原型视图。(在默认情况下,/browse视图假设gettingstarted的数据模式和数据会捕获所有类型的结构化数据(例如,XML、JSON、CSV,等等),以及未格式化的富文本文档。虽然/browse页面的模板是可以自定义的,但是你自己的数据可能一开始看起来不太理想。

3. 索引JSON文件

Solr可以为JSON数据创建索引,无论是任意结构化的JSON数据,还是“Solr JSON”格式的数据(类似于Solr XML格式的数据)。

Solr包含一个较新的Solr JSON格式的示例文件,可用于说明上述的这种能力。再次使用bin/post脚本,为JSON格式的示例文件建立索引:

  1. bin/post -c gettingstarted example/exampledocs/books.json

你在Shell中将会看到如下的输出信息:

导入JSON数据的输出信息

若要合并(或拆分)和索引任意结构化的JSON数据,你可以参考本教程之外的另一篇文章,了解如何转换和索引自定义的JSON数据[4]

4. 索引CSV文件

导入Solr的数据有很大一部分是CSV(Comma Separated Value,逗号分隔值)格式的,特别是当导入的数据都具有相同的字段时。你可以很方便地从电子表格(诸如Excel文件)中导出CSV文件,也可以从数据库(诸如MySQL)中导出CSV文件。当开始使用Solr时,你通常可以将结构化数据转换为CSV格式,然后为这些数据建立索引,并且存储在Solr之中,这通常要比较为复杂的单步操作更加简单。

使用bin/post脚本,为Solr包含的CSV示例文件创建索引:

  1. bin/post -c gettingstarted example/exampledocs/books.csv

你在Shell中将会看到如下的输出信息:

导入CSV数据的输出信息

5. 其他索引技术

  • 使用DIH(Data Import Handler,数据导入处理程序)[5],从一个数据库中导入记录。

  • 可以在Java应用程序中使用SolrJ[6],或者其他可编程的Solr客户端[7],这样就可以在程序中创建文档,然后发送给Solr。

  • 你可以在浏览器中打开Solr管理界面的指定核心的Documents标签页[8],这样你便能粘贴一个待索引的文档,或者在Document Type下拉菜单中选择文档构造器(Document Builder),这样便能构造指定字段格式的文档了。请点击表单下方的“Submit Document”按钮,为你的文档建立索引。

五、更新数据

你可能会注意到,即使你多次为本文档中的内容创建索引,你都不会找到重复的结果。这是因为示例的schema.xml[9]文件指定了一个“uniqueKey”字段,名为“id”。当你执行一个提交数据至Solr的命令时,如果待添加文档的uniqueKey字段的值和已有文档的相同时,Solr便会自动为你替换最新的值。你可以在浏览器中打开Solr管理界面的指定核心的Overview标签页[10],查看其中的“Num Docs”和“Max Doc”的值,这样便能确定是否添加的新值。

numDocs表示通过索引能够搜索到的文档总数(可能会大于XML、JSON或CSV文件的数量,因为某些文件可能会包含多个文档)。maxDoc的值可能会更大,因为maxDoc的计数值包含逻辑删除文档的数量,而这些文档还没有从索引中物理删除。你可以尽可能多地反复向Solr发布这些示例文件,你会发现numDocs从来不会增大,因为新的文档总是会替换旧的文档。

请继续学习下一章节,编辑任意已有的示例数据文件,然后重新运行SimplePostTool命令。你将会在后续的搜索结果中看到你修改过的数据。

六、删除数据

如果你想要删除数据,那么你可以在URL中添加一条删除命令,指定待删除文档的唯一键字段,也可以在URL中添加一条匹配多个文档的查询命令,然后在浏览器中访问这个URL。因为这些命令都比较短小,所以我们可以在命令行中直接使用这些命令,而不需要使用JSON或XML文件。

执行下面的命令,删除一个指定的文档:

  1. bin/post -c gettingstarted -d "<delete><id>SP2514N</id></delete>"

七、搜索数据

你可以通过REST客户端、curl、wget、Chrome POSTMAN等工具查询Solr,除此之外,很多编程语言还可以通过原生的客户端查询Solr。

Solr管理界面包含一个查询构造器接口 —— 请在查看以下页面的gettingstarted的Query标签页:http://192.168.21.129:8983/solr/#/gettingstarted_shard1_replica1/query。如果你没有修改表单中的任何内容就点击了“Execute Query”按钮,那么你将会获得10个JSON格式的文档(q参数框中的“:”匹配所有的文档),如下图所示:

快速入门的查询页面

Solr管理界面发送给Solr的URL在上图右上方的浅灰色地址栏中展示 —— 如果你点击这个URL,那么你的浏览器将会向你展示原始的响应信息。若要使用curl工具,那么请在curl命令之后添加这个URL参数,需要放在双引号之内。

  1. curl "http://192.168.21.129:8983/solr/gettingstarted/select?q=*%3A*&wt=json&indent=true"

在上述的URL中,“q=:”中的“:”符号已经被URL编码为“%3A”,但是因为“:”在URL的查询分量(URL的“?”符号之后的部分)中没有任何保留用途,所以你并不需要URL对其编码。因此,下面的命令同样有效:

  1. curl "http://192.168.21.129:8983/solr/gettingstarted/select?q=*:*&wt=json&indent=true"

1. 基础搜索

1.1 搜索单词

如果要搜索某个单词,那么请首先在Solr管理界面中打开指定核心的Query标签页,然后将这个页面的q参数框中的“:”替换为你想要搜索的单词。若要搜索“foundation”单词,请运行以下命令:

  1. curl "http://192.168.21.129:8983/solr/gettingstarted/select?wt=json&indent=true&q=foundation"

你可以在Shell中看到如下输出信息:

搜索单词输出结果

响应信息表示有2812个匹配结果(”numFound”:2812),但是响应信息只会返回前10个结果,因为使用了默认参数start=0和rows=10。你可以指定这些参数,便于分页浏览结果,start参数(从0开始)表示返回的首个结果的位置,row参数表示每页显示的记录行数。

若想要限制响应信息返回的字段,请使用fl参数,这个参数的值是一个逗号分隔的字段名列表。例如,若只要访问id字段,请运行以下命令:

  1. curl "http://192.168.21.129:8983/solr/gettingstarted/select?wt=json&indent=true&q=foundation&fl=id"

q=foundation几乎会匹配到我们已经索引的所有文档,因为docs/目录下的大多数文件都包含“The Apache Software Foundation”。若要限制搜索一个指定的字段,请使用“q=field:value”形式的参数,例如,若只要在name字段中搜索单词“foundation”,你可以运行以下命令:

  1. curl "http://192.168.21.129:8983/solr/gettingstarted/select?wt=json&indent=true&q=name:foundation"

上面的请求只会在响应信息中返回一个文档(”numFound”:1):

限制字段的搜索结果

1.2 搜索短语

若要搜索一条包含多个单词的短语,请将这个短语放在双引号中,例如:q=”multiple terms here”。例如,若要搜索“CAS latency”短语 —— 请注意,单词之间的空格在URL中会被转换为“+”符号(Solr管理界面会自动为你处理URL编码),请运行以下命令:

  1. curl "http://192.168.21.129:8983/solr/gettingstarted/select?wt=json&indent=true&q=\"CAS+latency\""

你可以在Shell中看到如下返回信息:

搜索短语结果

1.3 组合搜索

在默认情况下,当你在单词查询中搜索多个单词或短语时,Solr只需要其中一个单词存在于文档之中,就认为这个文档是匹配的。如果某个文档包含短语中的单词越多,那么它在结果列表中的排序次序就越高。

你可能会要求某个单词或短语存在于文档之中,请在这个单词或短语前面添加“+”符号作为前缀;相反,如果你不允许某个单词或短语存在于文档之中,请在这个单词或短语前面添加“-”符号作为前缀。

如果想要找到同时包含单词“one”和“three”的文档,那么请首先在Solr管理界面中打开指定核心的Query标签页,然后在这个页面的q参数框中填写“+one +three”。因为“+”字符在URL中具有保留用途(会被编码为空格),所以你必须将curl工具的URL参数中的“+”字符替换为“%2B”,你可以运行以下命令:

  1. curl "http://192.168.21.129:8983/solr/gettingstarted/select?wt=json&indent=true&q=%2Bone+%2Bthree"

若要搜索包含单词“two”,但不包含单词“one”的文档,请在q参数框中输入“+two -one”。你需要再一次将“+”符号替换为“%2B”,你可以运行以下命令:

  1. curl "http://192.168.21.129:8983/solr/gettingstarted/select?wt=json&indent=true&q=%2Btwo+-one"
1.4 深入理解

若要了解更多Solr的搜索选项,请参考《Solr参考指南》的“搜索”相关章节[11]

2. 分类搜索

Solr最受欢迎的一个功能特性便是分类搜索(Faceting Search)。分类使得搜索结果能够被排列为多个子集(或桶,或种类),每个子集都会有一个结果计数。Solr支持以下几种类型的分类搜索:字段值分类、数字和日期范围分类、中心点分类(决策树)和任意查询分类。

2.1 字段值分类

除了提供搜索结果之外,Solr的查询操作还会返回整个结果集中包含每个唯一值的文档的数量。

在Solr管理界面中打开指定核心的Query标签页,如果你勾选了“facet”复选框,你就可以在这个复选框下方看到一些分类相关的选项,如下图所示:

分类搜索选项

若要查看所有文档的分类计数(q=:):首先启用分类搜索(facet=true),然后通过facet.field参数指定待分类的字段。如果你只想查看分类计数,不想查看文档内容,那么请指定参数rows=0。下面的curl命令将会返回manu_id_s字段的分类计数:

  1. curl "http://192.168.21.129:8983/solr/gettingstarted/select?wt=json&indent=true&q=*:*&rows=0&facet=true&facet.field=manu_id_s"

你可以在Shell中看到如下的输出信息:

字段值分类的输出信息

2.2 数字和日期范围分类

对于数字或日期来说,经常希望获取几个取值范围的分类计数,而不是离散值的分类计数。Solr包含了一个使用商品价格(price)作为示例数据的数字取值范围的分类搜索示例。在/browse界面中,这个示例如下图所示:

分类搜索示例

若要得到JSON格式的商品价格范围搜索的结果,请运行下面的命令:

  1. curl "http://192.168.21.129:8983/solr/gettingstarted/select?q=*:*&wt=json&indent=on&rows=0&facet=true&facet.range=price&f.price.facet.range.start=0&f.price.facet.range.end=600&f.price.facet.range.gap=50&facet.range.other=after"

你可以在Shell中看到如下的输出信息:

价格范围搜索的JSON格式结果

2.3 中心点分类

另一种分类搜索便是中心点分类,也被称作决策树(Decision Tree),使得Solr在搜索时能够嵌套两个或更多个字段,这样便能搜索各种可能的组合。使用示例的科技商品数据,中心点分类可以用来查看“book”种类中有多少个有库存(In Stock)的商品,或者有多少个无库存(Not In Stock)的商品。你可以运行以下命令,得到上述场景的原始结果数据:

  1. curl "http://192.168.21.129:8983/solr/gettingstarted/select?q=*:*&rows=0&wt=json&indent=on&facet=on&facet.pivot=cat,inStock"

你可以在Shell中看到下面的结果(只显示book种类相关的输出信息),表示“book”种类中共有14个条目,其中:12个有库存,2个无库存。如下图所示:

中心点分类搜索结果

2.4 更多分类选项

若要充分理解Solr的分类搜索,请参考《Solr参考指南》的“分类搜索”相关章节[12]

3. 空间搜索[13]

Solr支持较为复杂的地理空间搜索,包括在某个给定位置的一个指定距离范围之内(或者在一个边界框之内)进行搜索,然后按距离进行排序,以至于根据距离提高结果的搜索速度。空间搜索的示例数据包含在example/exampledocs/*.xml文件中,这些文件包含的某些文档具有位置相关的信息。若要运行科技商品的示例,请参考techproducts示例的相关章节。空间搜索可以和其他的搜索类型相结合,正如下面的例子所示,查询“iPod”关键字便能得到距离旧金山10公里之内的结果:

空间搜索示例

空间检索的URL是http://192.168.21.129:8983/solr/techproducts/browse?q=ipod&pt=37.7752%2C-122.4232&d=10&sfield=store&fq=%7B%21bbox%7D&queryOpts=spatial&queryOpts=spatial/browse界面会显示一张地图,每个结果条目都会在地图上显示,你可以很轻松地选择想要搜索的地点。

若要了解更多关于Solr空间搜索的信息,请参考《Solr参考指南》的“空间搜索”相关章节[14]

八、总结

如果你已经运行过本文示例的所有命令,那么你已经完成了以下的事项:

  • 启动Solr至SolrCloud模式,具有两个节点,以及两个包含分片和复制的集合;

  • 为一个包含富文本文件的目录建立索引;

  • 为Solr XML文件建立索引;

  • 为CSV文件建立索引;

  • 打开管理控制台页面,使用它的查询接口获取JSON格式的结果;

  • 打开/browse界面,以一种更加友好和熟悉的方式探索Solr的功能特性。

干得漂亮!下面的脚本可以运行本文示例的所有命令,在两分钟之内就能运行完成!(你的运行时间可能会有所不同,取决于你的电脑的处理能力和可用资源。)

你可以拷贝和粘贴此处的Unix脚本,这样便能运行本文示例中的关键命令:

  1. date ;
  2. bin/solr start -e cloud -noprompt ;
  3. open http://192.168.21.129:8983/solr ;
  4. bin/post -c gettingstarted docs/ ;
  5. open http://192.168.21.129:8983/solr/gettingstarted/browse ;
  6. bin/post -c gettingstarted example/exampledocs/*.xml ;
  7. bin/post -c gettingstarted example/exampledocs/books.json ;
  8. bin/post -c gettingstarted example/exampledocs/books.csv ;
  9. bin/post -c gettingstarted -d "<delete><id>SP2514N</id></delete>" ;
  10. bin/solr healthcheck -c gettingstarted ;
  11. date ;

九、环境清理

当你学习完本文之后,你可能想要停止运行Solr,并且将环境重置回初始状态。此时,你可以运行下面的命令,停止运行Solr,然后删除启动脚本为每个节点创建的目录:

  1. bin/solr stop -all ; rm -Rf example/cloud/

十、下一步?

若要了解关于Solr的更多信息,请参考下面的资源:

  • 《Solr参考指南》[15](请确保你的参考手册的版本号和正在使用的Solr版本号相同)

  • 还可以参考其他的资源[16]


注释

[1]请参考:https://lucene.apache.org/solr/api/SYSTEM_REQUIREMENTS.html

[2]请参考:https://cwiki.apache.org/confluence/display/solr/Post+Tool#PostTool-Windows

[3]请参考:https://cwiki.apache.org/confluence/display/solr/Uploading+Data+with+Index+Handlers#UploadingDatawithIndexHandlers-XMLFormattedIndexUpdates

[4]请参考:https://cwiki.apache.org/confluence/display/solr/Uploading+Data+with+Index+Handlers#UploadingDatawithIndexHandlers-TransformingandIndexingcustomJSONdata

[5]请参考:https://cwiki.apache.org/confluence/display/solr/Uploading+Structured+Data+Store+Data+with+the+Data+Import+Handler

[6]请参考:https://cwiki.apache.org/confluence/display/solr/Using+SolrJ

[7]请参考:https://cwiki.apache.org/confluence/display/solr/Client+APIs

[8]在本例中,你可以访问http://192.168.21.129:8983/solr/#/gettingstarted_shard1_replica1/documentshttp://192.168.21.129:8983/solr/#/gettingstarted_shard2_replica1/documents

[9]该文件位于/usr/local/solr-5.3.1/example/example-DIH/solr/solr/conf目录

[10]在本例中,你可以访问http://192.168.21.129:8983/solr/#/gettingstarted_shard1_replica1http://192.168.21.129:8983/solr/#/gettingstarted_shard2_replica1

[11]请参考:https://cwiki.apache.org/confluence/display/solr/Searching

[12]请参考:https://cwiki.apache.org/confluence/display/solr/Faceting

[13]由于实验环境无法访问谷歌地图,因此就没有做空间检索部分的实验

[14]请参考:https://cwiki.apache.org/confluence/display/solr/Spatial+Search

[15]请参考:https://cwiki.apache.org/confluence/display/solr/Apache+Solr+Reference+Guide

[16]请参考:https://lucene.apache.org/solr/resources.html