Solr 快速入门手册

2018/05/30 Solr

Solr 是 Apache Lucene 项目的一个开源 Search Engine,支持全文检索。最近工作中用到,初步记录一些 Linux 环境下的使用方式。

环境: CentOS 7.x, JDK 1.8.0_162

1. Solr 安装

安装过程参考教程:Solr快速入门教程

Solr 其实并不需要安装。在官网下载了压缩包之后解压,进入目录,通过 ./bin/solr 即可运行。 有点像 Windows 下的“绿色解压版”软件。

在用 root 用户运行 bin/solr start -e cloud -noprompt 的时候,发生错误:

ERROR: Failed to start Solr using command: "bin/solr" start -cloud -p 8983 -s "example/cloud/node1/solr" Exception : org.apache.commons.exec.ExecuteException: Process exited with an error: 1 (Exit value: 1)

切换一个普通用户账户重新运行后,不再出现上面的报错,但是出现新的错误:

ERROR: Logs directory /usr/local/solr-7.3.1/example/cloud/node1/solr/../logs could not be created. Exiting

ERROR: Failed to start Solr using command: "/usr/local/solr-7.3.1/bin/solr" start -cloud -p 8983 -s "/usr/local/solr-7.3.1/example/cloud/node1/solr" Exception : org.apache.commons.exec.ExecuteException: Process exited with an error: 1 (Exit value: 1)

因为之前一直用 root 用户操作,现在切换成普通用户会有权限的问题。我直接把这个目录改成所有人都可以读写:

$ chmod 777 /usr/local/solr-7.3.1/ -R

之后就能正常运行啦。

2. Solr 基本操作

2.1 启动 Solr

首先进入 Solr 目录下,运行:

$ bin/solr start

这样是按照默认的 8983 的端口号启动服务,端口号可以用 -p 参数指定。另外,加上 -f 参数,可以让程序在前台运行。

如果不带参数,默认是在后台运行的。可以运行 bin/solr stop 停止服务。

运行 bin/solr status 可以查看 Solr 的运行状态。

2.2 创建一个 core

启动服务后,需要先创建一个 demo 的 core:

$ bin/solr create -c demo

关于 core 的概念,可以参考 [3] 中的这段话:

一个core主要是一个文档集中text和field的索引。 一个solr实例可以包含多个core,每个core根据本地一定的标准互相分开。 它去提供结不同的搜索接口给用户,或者提供权限让不同用户有不同权限去访问不同文档。

2.3 导入数据

如果想简单地导入一些数据来测试,可以直接用 curl + url 的方式。一个例子:

$ curl http://localhost:8983/solr/demo/update -d '
[
 {"id" : "book1",
  "title_t" : "The Way of Kings",
  "author_s" : "Brandon Sanderson"
 }
]'

如果要批量导入数据,需要写脚本调用 Solr 的接口。比较方便的是,Solr 自带了一个 post 工具,封装了一些方法,支持批量导入数据。

运行:

$ bin/post -c demo -params "separator=%09" -type text/csv mydata/*

我的数据是用 \t 分隔的纯文本文件。因为 csv 格式默认的分隔符是逗号,所以按照 text/csv 的类型导入的时候需要指定分隔符。

在 csv 文件的第一行,需要定义 field 的名称和类型。具体定义可以参考 Solr Tutorial 中的“Dynamic Fields”的部分。示例:

skuId_s	commentId_l	dt_s	commentSegment_s	parsedSegment_t

顺便记录一下,我的数据总量是 310+ G,导入大约花了 15 小时。

2.4 查看导入的数据

查看数据也是通过 http 请求,需要用查询语句来查询。Solr 有一套自己的查询语法,如果对 SQL 有了解的话能很快上手。

查看所有数据:

$ curl 'http://localhost:8983/solr/demo/query?q=*'

查看 schema:

$ curl 'http://localhost:8983/solr/demo/admin/luke?show=schema&wt=json'

2.5 删除所有导入的数据

运行:

$ curl 'http://localhost:8983/solr/demo/update?stream.body=<delete><query>*:*</query></delete>'
$ curl 'http://localhost:8983/solr/demo/update?stream.body=<commit/>'

删除操作需要 commit 之后才能生效。

第一次运行这个命令的时候,发生一个错误:

{
  "error":{
    "metadata":[
      "error-class","org.apache.solr.common.SolrException",
      "root-error-class","org.apache.solr.common.SolrException"],
    "msg":"Stream Body is disabled. See http://lucene.apache.org/solr/guide/requestdispatcher-in-solrconfig.html for help",
    "code":400}
}

“Stream Body is disabled”说明 Stream Body 不可用,需要手动 enable 一下。运行:

$ curl http://localhost:8983/solr/demo/config -H 'Content-type:application/json' -d'{
    "set-property" : {"requestDispatcher.requestParsers.enableRemoteStreaming":true},
    "set-property" : {"requestDispatcher.requestParsers.enableStreamBody":true}
}'

2.6 其他

打印所有的 core 信息:

$ curl 'http://localhost:8983/solr/admin/cores?action=STATUS'

返回的结果如下: solr_core_info

从 core 的状态信息里,可以看到数据导入的进度。

3. 踩了一些小坑

3.1 关于索引

Feb 25, 2019 更新 见:Solr 对文本索引及其查询

3.2 query 和 select 语句

在看各种教程的时候,发现有一些用 query 来查询,有一些用 select 来查询,查询的结果看起来没什么不同。

查了一下这俩用什么不同。参考:Difference between /select & /query handlers in solr

摘抄一段答案:

The answer to this depends on the contents of your solrconfig.xml, as that is the configuration file where the different requestHandlers are defined. If you search that file for and , you should be able to find what the difference is.

这里的意思是说,queryselect 的查询行为,是在 solrconfig.xml 配置文件里定义好的。如果想看有什么不同,直接看配置文件就行。而配置文件可以自己修改,还能自定义新的 requestHandler,所以不用太探究这俩有什么不一样。

配置文件在 server 目录下:

solr-7.3.1/server/solr/configsets/sample_techproducts_configs/conf/solrconfig.xml

3.3 导入数据加速

导入数据的时候,查了一下如何加速导入数据,虽然最后用上,写在这里留作参考。

耗时太大基本是 indexing 引起的,所以对于索引的字段,能精简就精简。

这次我就比较愚蠢地直接对于整个 json 做索引了。实际上我只需要对 json 中叶节点的部分 value 建立索引。更好的做法是单独建立一个 field,把需要建索引的部分抽出来放在这个 field 中。

3.4 update 和 commit

如果执行 update 之后查询不到数据,可能是因为没有 commit。运行:

curl 'http://localhost:8983/solr/demo/update?commit=true'

3.5 url 中的中文和空格

在命令行访问的时候,需要把 url 中的中文和空格转码为 % 开头的编码格式。

写了一个脚本来转:

#coding=utf8
import sys
import urllib.parse
import traceback

keyword = '测试'
try:
    url = "http:/127.0.0.1:8983/solr/demo/query?q=titile_t:" + \
           urllib.parse.quote(keyword, "utf-8")
    print(url)
except:
    traceback.print_exc()

3.6 返回结果数限制

curl + url 的方式来查询 Solr 数据,默认只会返回 10 个结果。如果返回全部的数据,可以通过加上一个 rows 参数并将其设置为一个极大值来解决。

在实际运行过程中,我把 rows 设置为 1000000,但这个引发了 Out of Memory (OOM)。这需要对 Solr 服务重新设置内存大小并重启。参考官方文档 Choosing Memory Heap Settings

参考

Solr Tutorial

用Solr构建垂直搜索引擎

solr的collection,shard,replica,core概念

Search

    Table of Contents