由于现公司要强化一下搜索相关的功能,特对Solr及Lucene进行简要的研究,并做一些个人总结。
Solr采用Lucene搜索库为核心,提供全文索引和搜索的开源企业平台,提供REST的HTTP/XML和JSON的API。
Solr项目的英文主页:http://lucene.apache.org/solr/,其中介绍了Solr的基本情况:Solr is highly reliable, scalable and fault tolerant, providing distributed indexing, replication and load-balanced querying, automated failover and recovery, centralized configuration and more. Solr powers the search and navigation features of many of the world's largest internet sites.
1. 下载并开始启动系统
我们可以从教程中的起始页面中开始我们的solr探索之旅:http://lucene.apache.org/solr/quickstart.html
将solr的jar包解压后,就可以在/bin目录下启动solr,执行命令后的结果为:
./solr start -e cloud -noprompt Welcome to the SolrCloud example! Starting up 2 Solr nodes for your example SolrCloud cluster. Creating Solr home directory /Users/mazhiqiang/develop/tools/solr-5.5.0/example/cloud/node1/solr Cloning /Users/mazhiqiang/develop/tools/solr-5.5.0/example/cloud/node1 into /Users/mazhiqiang/develop/tools/solr-5.5.0/example/cloud/node2 Starting up Solr on port 8983 using command: /Users/mazhiqiang/develop/tools/solr-5.5.0/bin/solr start -cloud -p 8983 -s "/Users/mazhiqiang/develop/tools/solr-5.5.0/example/cloud/node1/solr" Waiting up to 30 seconds to see Solr running on port 8983 [/] Started Solr server on port 8983 (pid=2835). Happy searching! Starting up Solr on port 7574 using command: /Users/mazhiqiang/develop/tools/solr-5.5.0/bin/solr start -cloud -p 7574 -s "/Users/mazhiqiang/develop/tools/solr-5.5.0/example/cloud/node2/solr" -z localhost:9983 Waiting up to 30 seconds to see Solr running on port 7574 [/] Started Solr server on port 7574 (pid=2931). Happy searching! Connecting to ZooKeeper at localhost:9983 ... Uploading /Users/mazhiqiang/develop/tools/solr-5.5.0/server/solr/configsets/data_driven_schema_configs/conf for config gettingstarted to ZooKeeper at localhost:9983 Creating new collection 'gettingstarted' using command: http://localhost:8983/solr/admin/collections?action=CREATE&name=gettingstarted&numShards=2&replicationFactor=2&maxShardsPerNode=2&collection.configName=gettingstarted { "responseHeader":{ "status":0, "QTime":6977}, "success":{"":{ "responseHeader":{ "status":0, "QTime":6686}, "core":"gettingstarted_shard2_replica2"}}} Enabling auto soft-commits with maxTime 3 secs using the Config API POSTing request to Config API: http://localhost:8983/solr/gettingstarted/config {"set-property":{"updateHandler.autoSoftCommit.maxTime":"3000"}} Successfully set-property updateHandler.autoSoftCommit.maxTime to 3000 SolrCloud example running, please visit: http://localhost:8983/solr
通过控制台中的输出内容,或者查看jps可以发现,solr启动了两个进程,分别对应两个端口8983,以及7574:
jps -ml 2835 start.jar -XX:OnOutOfMemoryError=/Users/mazhiqiang/develop/tools/solr-5.5.0/bin/oom_solr.sh 8983 /Users/mazhiqiang/develop/tools/solr-5.5.0/example/cloud/node1/solr/../logs --module=http 2931 start.jar -XX:OnOutOfMemoryError=/Users/mazhiqiang/develop/tools/solr-5.5.0/bin/oom_solr.sh 7574 /Users/mazhiqiang/develop/tools/solr-5.5.0/example/cloud/node2/solr/../logs --module=http 344 3004 sun.tools.jps.Jps -ml
可以在服务器的对应端口上,查看到solr的example页面:http://localhost:8983/solr/#/
同样,如果将端口换成7574页面与8983一致。
也可以在cloud tab中看到整体结构图,solr运行在两个节点上:
2.索引数据(Indexing Data)
系统启动完成后,solr server就已经在后台运行了,但是其中什么数据都没有。Solr在bin目录中提供了一个post工具,用于一开始就帮助方便地向solr中添加各种类型的documents。
可以使用post工具来处理类似html, pdf, ms-office, plain text等各种格式的文本,可以根据目录去递归爬取文件至Solr,用于抽取(extraction)和索引(indexing)。
调用bin/post -c gettingstarted docs/ 来加入所有docs目录下的文档,在控制台中输出如下:
bin/post -c gettingstarted docs/ /Library/Java/JavaVirtualMachines/jdk1.8.0_05.jdk/Contents/Home/bin/java -classpath /Users/mazhiqiang/develop/tools/solr-5.5.0/dist/solr-core-5.5.0.jar -Dauto=yes -Dc=gettingstarted -Ddata=files -Drecursive=yes org.apache.solr.util.SimplePostTool docs/ SimplePostTool version 5.0.0 Posting files to [base] url http://localhost:8983/solr/gettingstarted/update... Entering auto mode. File endings considered are xml,json,jsonl,csv,pdf,doc,docx,ppt,pptx,xls,xlsx,odt,odp,ods,ott,otp,ots,rtf,htm,html,txt,log Entering recursive mode, max depth=999, delay=0s Indexing directory docs (3 files, depth=0) POSTing file index.html (text/html) to [base]/extract POSTing file quickstart.html (text/html) to [base]/extract POSTing file SYSTEM_REQUIREMENTS.html (text/html) to [base]/extract Indexing directory docs/changes (1 files, depth=1) POSTing file Changes.html (text/html) to [base]/extract Indexing directory docs/images (0 files, depth=1) Indexing directory docs/solr-analysis-extras (8 files, depth=1)
可以看出,是根据目录去逐层Indexing,并POSTing至Solr中,直至所有的文档都已经处理完成,共处理约4000个文件。
POSTing file VelocityResponseWriter.html (text/html) to [base]/extract Indexing directory docs/solr-velocity/resources (0 files, depth=2) 3937 files indexed. COMMITting Solr index changes to http://localhost:8983/solr/gettingstarted/update... Time spent: 0:01:12.141
注意,这里的-c gettingstarted为索引的集合名称(暂时不知道干什么用的)。
在上一步已经执行完成后,就可以在搜索页面中进行查询(其中需要带上collection的名称),并查询出结果:
具体查询的方式可以看solr相关的wiki,可以独立一篇详细研究。
也可以通过collection的browse方式来查询出所有的POSTing过去的数据:
除了可以索引这些通用的文档数据类型,solr还支持索引XML(称之为Solr Xml),JSON(称之为Solr JSON),CSV文件(用逗号,停顿分列的值)。这些文件类型都是solr默认支持的,此外还提供几种其他的方式来indexing数据:
- Import records from a database using the Data Import Handler (DIH);如果需要导入数据库的记录,使用DIH;
- Use SolrJ from JVM-based languages or other Solr clients to programatically create documents to send to Solr;如果需要从基于JVM的语言或其他Solr客户端自动程序化地创建文档,使用SolrJ;
- Use the Admin UI core-specific Documents tab to paste in a document to be indexed, or select Document Builder from the Document Type dropdown to build a document one field at a time. Click on the Submit Document button below the form to index your document;可以选择从Solr的文档中心中粘贴Documents的方式来indexing数据,例如:http://localhost:8983/solr/#/gettingstarted_shard2_replica1/documents;
3.更新数据
可以注意到,即使你将index的内容重复操作,执行多次,对于最终的结果而言,也不会重复,这是因为我们启动的solr example项目的配置文件中:
solr-5.5.0/example/files/conf/managed-schema
已经指定了uniqueKey作为最终的id;而当你POST一个新的文档至Solr中试图index同样的uniqueKey时,会自动进行替换的操作。
4.删除数据
可以通过POST命令的方式,指定要删除的unique key字段,或是指定一个查询条件来匹配多个文档(如果这样操作的话,要多加小心!)。
可以调用下面的命令从gettingstarted collection删除指定id的数据:
/bin/post -c gettingstarted -d “<delete><id>1212312312dfasfd</id></delete>"
5.执行搜索
Solr可以通过多种方式进行查询操作,比如Rest客户端,curl, wget, Chrome POSTMAN,以及通过各种编程语言的客户端来进行查询操作。
Solr Admin UI包含了一个查询构建接口编辑器,启动Solr的相关地址为:
如果使用默认的条件查询,不用输入任何条件,此时就会默认返回10条记录,用json的格式:
在右上的顶部会自动将请求的url填写上去,如果在Linux/Mac上使用curl工具,可以给同样的url来进行查询工作,例如:
curl "http://localhost:8983/solr/gettingstarted_shard1_replica1/select?q=*%3A*&wt=json&indent=true"
q字段也就是查询使用的字段:
- 如果设置为*:*,表示不过滤任何字段,全部查询出来;
- 如果设置为foundation,表示只要文档中包含foundation,就查询出来;
- 如果设置为name:foundation,指的是匹配名称name为foundation的文档,如果name这个字段并没有设置(所有文档都没有这个属性),则出现错误;
- 如果要查询一个短语,其中包含多个词,可以使用q=CAS+foundation的方式,表示查询的字段为“CAS foundation”;
- 如果要限制查询出来的字段仅包含某个或某几个属性,使用fl字段,例如fl=id,多个可以用逗号分隔;
- 如果需要搜索既包含one又包含two的文档,可以使用+前缀,q=%2Bone+%2Btwo(由于加号在q字段中表示空格,因此需要转义);反之,如果需要搜索到包含one但不包含two的文档,使用-前缀,q=%2Bone+-two;
如果需要更加深入地了解solr中的查询,可以参考solr关于查询的wiki:https://cwiki.apache.org/confluence/display/solr/Searching
6.清理
我们刚才导入了很多的数据,如果需要从初始环境开始,那么就需要对当前的环境进行清理,并删除Index进来的所有数据:
bin/solr stop -all; rm -Rf example/cloud/
<!--?xml version="1.0" encoding="UTF-8" standalone="no"?-->
Solr脚本选项
可以使用bin/solr脚本工具来进行,需要使用bin/solr脚本,执行
./solr -help
如果需要看特定指令的帮助,例如start命令,可以使用
./solr start -help
一般情况下,执行./solr start命令是在后台启动的,如果想将其放到前台(foreground),可以使用
./solr start -f
可以通过-p指定启动端口,默认端口为8983,
当命令并没有在前台执行时,可以使用solr的stop命令来终止特定端口下的solr,
./solr stop -p 8983 Sending stop command to Solr running on port 8983 ... waiting 5 seconds to allow Jetty process 2835 to stop gracefully.
此时可以发现另外的solr实例仍然运行(默认还存在一个占用端口为7574的实例,其管理界面仍然是可用的),如果想要将所有的实例都kill掉,可以在stop后面加 -all。
在下载的solr完整包中我们可以直接使用solr提供的examples帮助我们迅速了解其关键性能,调用:
./solr -e techproducts Solr home directory /Users/mazhiqiang/develop/tools/solr-5.5.0/example/techproducts/solr already exists. Starting up Solr on port 8983 using command: /Users/mazhiqiang/develop/tools/solr-5.5.0/bin/solr start -p 8983 -s "/Users/mazhiqiang/develop/tools/solr-5.5.0/example/techproducts/solr" Waiting up to 30 seconds to see Solr running on port 8983 [/] Started Solr server on port 8983 (pid=4113). Happy searching! Copying configuration to new core instance directory: /Users/mazhiqiang/develop/tools/solr-5.5.0/example/techproducts/solr/techproducts Creating new core 'techproducts' using command: http://localhost:8983/solr/admin/cores?action=CREATE&name=techproducts&instanceDir=techproducts { "responseHeader":{ "status":0, "QTime":1945}, "core":"techproducts"} Indexing tech product example docs from /Users/mazhiqiang/develop/tools/solr-5.5.0/example/exampledocs SimplePostTool version 5.0.0 Posting files to [base] url http://localhost:8983/solr/techproducts/update using content-type application/xml... POSTing file gb18030-example.xml to [base] POSTing file hd.xml to [base] POSTing file ipod_other.xml to [base] POSTing file ipod_video.xml to [base] POSTing file manufacturers.xml to [base] POSTing file mem.xml to [base] POSTing file money.xml to [base] POSTing file monitor.xml to [base] POSTing file monitor2.xml to [base] POSTing file mp500.xml to [base] POSTing file sd500.xml to [base] POSTing file solr.xml to [base] POSTing file utf8-example.xml to [base] POSTing file vidcard.xml to [base] 14 files indexed. COMMITting Solr index changes to http://localhost:8983/solr/techproducts/update... Time spent: 0:00:00.488 Solr techproducts example launched successfully. Direct your Web browser to http://localhost:8983/solr to visit the Solr Admin UI
默认启用8983端口,此时只会启动一个实例。如果不确定solr是否已经在运行,使用staus命令来查看:
./solr status Found 1 Solr nodes: Solr process 4113 running on port 8983 { "solr_home":"/Users/mazhiqiang/develop/tools/solr-5.5.0/example/techproducts/solr", "version":"5.5.0 2a228b3920a07f930f7afb6a42d0d20e184a943c - mike - 2016-02-16 15:22:52", "startTime":"2016-04-07T01:46:13.62Z", "uptime":"0 days, 0 hours, 9 minutes, 51 seconds", "memory":"56.8 MB (%11.6) of 490.7 MB"}
可以看到我们通过-e techproducts启动的进程,只会启动一个Solr节点(因为我们并没有采用Cloud模式),这边甚至可以看出其内存占用率。
最简单的查询,可以在浏览器中写下下面的url:
注意URL中主要包含主机名(localhost),端口号(8983),应用名称(solr),请求查询的处理器(select),最后是查询(q=video),最终出来的结果为xml格式,当然也可以非常容易地切换成不同的输出格式,例如JSON,PHP,Ruby,或者用户自定义格式。
<response> <lst name="responseHeader"> <int name="status">0</int> <int name="QTime">4</int> <lst name="params"> <str name="q">video</str> </lst> </lst> <result name="response" numFound="3" start="0"> <doc> <str name="id">MA147LL/A</str> <str name="name">Apple 60 GB iPod with Video Playback Black</str> <str name="manu">Apple Computer Inc.</str> <str name="manu_id_s">apple</str> <arr name="cat"> <str>electronics</str> <str>music</str> </arr> <arr name="features"> <str>iTunes, Podcasts, Audiobooks</str> <str> Stores up to 15,000 songs, 25,000 photos, or 150 hours of video </str> <str> 2.5-inch, 320x240 color TFT LCD display with LED backlight </str> <str>Up to 20 hours of battery life</str> <str>
这里就是根据最新版本5.5.0相关文档而编写的简要入门文档,对于solr的进一步入门,我们后续再继续探讨