Solr 基础教程

准备环境

本教程基于 Solr 7.7 官方文档
JDK 要求:java8+

在开始本教程前,推荐使用虚拟机构建 3 台 Linux 系统服务,用于服务的搭建和部署以及环境的隔离。

笔者在本地使用了两台 CentOS 7 的机器来部署 Demo 服务。

下载并解压 Solr

Solr 官方的下载地址:https://solr.apache.org/downloads.html
9.0 之前版本的 Lucene 地址:https://archive.apache.org/dist/lucene/solr/

下载好的 Solr 压缩包进行解压:

[root@stackstone-002 solr]# pwd
/opt/solr
[root@stackstone-002 solr]# ls
solr-7.7.2.tgz
[root@stackstone-002 solr]# tar -zxvf solr-7.7.2.tgz

解压后进入到 solr-7.7.2 目录中,其结构如下:

[root@stackstone-002 solr-7.7.2]# pwd
/opt/solr/solr-7.7.2
[root@stackstone-002 solr-7.7.2]# ls -lh
总用量 1.6M
drwxr-xr-x.  3 root root  147 1月   3 09:59 bin
-rw-r--r--.  1 root root 821K 5月  21 2019 CHANGES.txt
drwxr-xr-x. 11 root root  190 5月  29 2019 contrib
drwxr-xr-x.  4 root root 4.0K 1月   3 09:59 dist
drwxr-xr-x.  3 root root   38 1月   3 09:59 docs
drwxr-xr-x.  6 root root   88 1月   3 09:59 example
drwxr-xr-x.  2 root root  28K 1月   3 09:59 licenses
-rw-r--r--.  1 root root  13K 5月  17 2019 LICENSE.txt
-rw-r--r--.  1 root root 689K 5月  28 2019 LUCENE_CHANGES.txt
-rw-r--r--.  1 root root  26K 5月  17 2019 NOTICE.txt
-rw-r--r--.  1 root root 7.4K 5月  17 2019 README.txt
drwxr-xr-x. 10 root root  157 1月   3 09:59 server

练习1:索引 Techproducts 样例数据

本练习会启动 2 个节点的 solr 集群并在启动时创建 Collection。随后我们索引一些样例数据并装配 Solr 并执行一些基础查询。

用 SolrCloud 模式启动 Solr

启动 Solr:

  • 类 Unix 系统:bin/solr start -e cloud;
  • Windows 系统:bin\solr.cmd start -e cloud;

我们会启动两个 Solr 服务,这个命令有一个选项 -noprompt 可以在不提升输入的情况下运行,由于我们需要修改其中两个默认值,所以我们不使用该选项。

[root@stackstone-002 solr-7.7.2]# ./bin/solr start -e cloud
*** [WARN] *** Your open file limit is currently 1024.
 It should be set to 65000 to avoid operational disruption.
 If you no longer wish to see this warning, set SOLR_ULIMIT_CHECKS to false in your profile or solr.in.sh
*** [WARN] ***  Your Max Processes Limit is currently 45841.
 It should be set to 65000 to avoid operational disruption.
 If you no longer wish to see this warning, set SOLR_ULIMIT_CHECKS to false in your profile or solr.in.sh

Welcome to the SolrCloud example!

This interactive session will help you launch a SolrCloud cluster on your local workstation.
To begin, how many Solr nodes would you like to run in your local cluster? (specify 1-4 nodes) [2]:

NOTE:
上面的命令打印出了 WARN 信息,Apache Solr在启动时会检查系统的某些资源限制设置,以确保它能在最佳状态下运行。你所看到的这两条警告信息是关于这些资源限制的。

  1. 打开文件限制(Open File Limit): 当前设置为1024。这个限制是指一个进程可以同时打开的最大文件数量。Solr需要能够打开许多文件,尤其是在处理大量数据时。如果这个限制太低,可能会导致Solr无法打开更多的文件,进而影响其性能和稳定性。因此,Solr建议将这个限制提高到65000。
  2. 最大进程限制(Max Processes Limit): 当前设置为45841。这个限制是指一个用户可以拥有的最大进程数。与打开文件限制类似,如果这个限制太低,可能会限制Solr的性能,尤其是在高负载情况下。Solr同样建议将这个限制提高到65000。

如果不希望看到这个提示,可以在 solr.in.sh 中设置 SOLR_ULIMIT_CHECKS 为 false。

如何更改 Linux 相关设置
在CentOS 7上修改文件打开限制和进程限制通常涉及以下步骤:

  1. 编辑limits.conf文件:

    • 打开/etc/security/limits.conf文件。你可以使用文本编辑器,如vinano
    • 在文件末尾添加或修改以下行:
      * soft nofile 65000
      * hard nofile 65000
      * soft nproc 65000
      * hard nproc 65000
      
    • 这里*代表所有用户,nofile代表打开文件的数量限制,nproc代表进程数量限制。soft限制是警告限制,hard限制是硬性限制。
  2. 修改systemd的限制:

    • CentOS 7使用systemd,你可能还需要修改systemd的限制。
    • 编辑或创建/etc/systemd/system.conf文件,添加或修改以下行:
      DefaultLimitNOFILE=65000
      DefaultLimitNPROC=65000
      
    • 这将为所有通过systemd启动的服务设置默认限制。
  3. 应用更改:

    • 完成编辑后,保存文件并关闭编辑器。
    • 为了让更改生效,你需要重启系统或重新登录。
  4. 验证更改:

    • 重启后,你可以使用ulimit -Hnulimit -Hu命令来验证硬性限制是否已正确设置。

第一个提示询问我们想运行多少节点,默认启动 2 个节点,所以这里我们直接输入回车(enter)键。

Ok, let's start up 2 Solr nodes for your example SolrCloud cluster.
Please enter the port for node1 [8983]:

这里指定第一个节点运行的端口,默认为 8983,这里可以根据自己需要进行端口的更改,如果不需要修改直接输出回车键。

Please enter the port for node2 [7574]:

这里需要指定第二个节点的运行端口,这里我将其改成了8984。

如果控制台显示:

Creating Solr home directory /opt/solr/solr-7.7.2/example/cloud/node1/solr
Cloning /opt/solr/solr-7.7.2/example/cloud/node1 into
   /opt/solr/solr-7.7.2/example/cloud/node2

Starting up Solr on port 8983 using command:
"bin/solr" start -cloud -p 8983 -s "example/cloud/node1/solr"

WARNING: Starting Solr as the root user is a security risk and not considered best practice. Exiting.
         Please consult the Reference Guide. To override this check, start with argument '-force'

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)

该问题是由于尝试以root用户身份启动Apache Solr造成的。Solr出于安全考虑,默认不允许以root用户运行,因为这会带来潜在的安全风险。运行Solr或类似的服务时,使用具有较少权限的用户是一种更安全的做法。

解决方法为两个步骤:

  1. 创建非root用户:
    • 在你的系统上创建一个新用户,专门用于运行Solr。
    • 你可以使用adduser命令创建新用户。例如,adduser solruser。
  2. 以新用户身份运行Solr:
    • 使用su或sudo命令切换到新创建的用户,然后再次尝试启动Solr。
    • 例如,使用su - solruser切换用户,然后再执行Solr的启动命令。

如果你确实需要以root用户身份启动Solr,可以添加-force参数来覆盖安全检查:
./bin/solr start -e cloud -force

如正常运行会显示:

Starting up Solr on port 8983 using command:
"bin/solr" start -cloud -p 8983 -s "example/cloud/node1/solr" -force

Waiting up to 180 seconds to see Solr running on port 8983 [\]
Started Solr server on port 8983 (pid=2586). Happy searching!


Starting up Solr on port 8984 using command:
"bin/solr" start -cloud -p 8984 -s "example/cloud/node2/solr" -z localhost:9983 -force

Waiting up to 180 seconds to see Solr running on port 8984 [\]
Started Solr server on port 8984 (pid=2757). Happy searching!

INFO  - 2024-01-03 11:04:54.720; org.apache.solr.common.cloud.ConnectionManager; zkClient has connected
INFO  - 2024-01-03 11:04:54.744; org.apache.solr.common.cloud.ZkStateReader; Updated live nodes from ZooKeeper... (0) -> (2)
INFO  - 2024-01-03 11:04:54.767; org.apache.solr.client.solrj.impl.ZkClientClusterStateProvider; Cluster at localhost:9983 ready

此处启动了两个solr实例,因为我们使用的是 SolrCloud 模式,而且我们并没有指定外部 ZooKeeper 集群,Solr 会启动其自身的 Zookeeper 并且两个节点均连接到该 Zookeeper。

启动完成后,我们需要创建一个 Collection。

Now let's create a new collection for indexing documents in your 2-node cluster.
Please provide a name for your new collection: [gettingstarted]

此处我们将collection命名为“techproducts”。

How many shards would you like to split techproducts into? [2]

此处询问我们在这两个节点上将索引拆分成多少分片(Shard),默认值是 2 意味着我们将在两个节点上相对均匀地分割索引,我们此处直接使用该默认值。

How many replicas per shard would you like to create? [2]

副本 (replica) 是用于故障转移的索引副本(可参阅 Solr Glossary definition ),我们此处也用该默认值,指定每个 Shard 创建 2 个副本。

Please choose a configuration for the techproducts collection, available options are:
_default or sample_techproducts_configs [_default]

Solr 有两个开箱即用的配置文件示例集(称为 configSet)。
一个集合必须有一个 configSet,它至少包含 Solr 的两个主要配置文件:模式文件(名为 Managed-Schema 或 schema.xml)和 solrconfig.xml。
这里的问题是想让我们从哪个 configSet 开始。 _default 是一个简单的选项,但请注意,有一个名称包含“techproducts”,该选项与我们的集合命名的名称相同。这个 configSet 是专门为支持我们想要使用的示例数据而设计的,因此在提示符下输入sample_techproducts_configs并按回车键。

到此处,Solr 将创建 Collection 并在控制台输出如下信息:

Created collection 'techproducts' with 2 shard(s), 2 replica(s) with config-set 'techproducts'

Enabling auto soft-commits with maxTime 3 secs using the Config API

POSTing request to Config API: http://localhost:8983/solr/techproducts/config
{"set-property":{"updateHandler.autoSoftCommit.maxTime":"3000"}}
Successfully set-property updateHandler.autoSoftCommit.maxTime to 3000


SolrCloud example running, please visit: http://localhost:8983/solr

此时 Solr 已经启动成功,可以准备数据了。

我们可以访问 Solr 的 Admin UI 管理界面:http://localhost8983/solr/。

Solr 现在运行了两个节点,一个端口号是 8983,另一个是 8984。自动创建了一个 collection techproducts,两个 shard 每个有两个副本。

在这里插入图片描述
在这里插入图片描述

索引 Techproducts 数据

现在 Solr 服务已经启动,但还没有任何数据,不能查询。
Solr 包含 bin/post 工具,以便于轻松索引各种类型的文档。我们将在下面的索引示例中使用此工具。

NOTE:
目前 bin/post 工具没有类似的 Windows 脚本,但调用的底层 Java 程序是可用的。
下面展示了 Windows 的示例,可以参阅发布工具文档的 Windows 部分以了解更多详细信息。

我们要索引的数据位于 example/exampledocs 目录下,这些文档采用多种文档格式(例如:JSON,CSV 等),我们可以一次性全部索引他们。

Linux/Mac

solr-7.7.0:$ bin/post -c techproducts example/exampledocs/*

Windows

C:\solr-7.7.0> java -jar -Dc=techproducts -Dauto example\exampledocs\post.jar example\exampledocs\*

执行上述命令后,会看到类似如下的输出:

[root@stackstone-002 solr-7.7.2]# bin/post -c techproducts example/exampledocs/*
java -classpath /opt/solr/solr-7.7.2/dist/solr-core-7.7.2.jar -Dauto=yes -Dc=techproducts -Ddata=files org.apache.solr.util.SimplePostTool example/exampledocs/books.csv example/exampledocs/books.json example/exampledocs/gb18030-example.xml example/exampledocs/hd.xml example/exampledocs/ipod_other.xml example/exampledocs/ipod_video.xml example/exampledocs/manufacturers.xml example/exampledocs/mem.xml example/exampledocs/money.xml example/exampledocs/monitor2.xml example/exampledocs/monitor.xml example/exampledocs/more_books.jsonl example/exampledocs/mp500.xml example/exampledocs/post.jar example/exampledocs/sample.html example/exampledocs/sd500.xml example/exampledocs/solr-word.pdf example/exampledocs/solr.xml example/exampledocs/test_utf8.sh example/exampledocs/utf8-example.xml example/exampledocs/vidcard.xml
SimplePostTool version 5.0.0
Posting files to [base] url http://localhost:8983/solr/techproducts/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
POSTing file books.csv (text/csv) to [base]
POSTing file books.json (application/json) to [base]/json/docs
POSTing file gb18030-example.xml (application/xml) to [base]
POSTing file hd.xml (application/xml) to [base]
POSTing file ipod_other.xml (application/xml) to [base]
POSTing file ipod_video.xml (application/xml) to [base]
POSTing file manufacturers.xml (application/xml) to [base]
POSTing file mem.xml (application/xml) to [base]
POSTing file money.xml (application/xml) to [base]
POSTing file monitor2.xml (application/xml) to [base]
POSTing file monitor.xml (application/xml) to [base]
POSTing file more_books.jsonl (application/json) to [base]/json/docs
POSTing file mp500.xml (application/xml) to [base]
POSTing file post.jar (application/octet-stream) to [base]/extract
POSTing file sample.html (text/html) to [base]/extract
POSTing file sd500.xml (application/xml) to [base]
POSTing file solr-word.pdf (application/pdf) to [base]/extract
POSTing file solr.xml (application/xml) to [base]
POSTing file test_utf8.sh (application/octet-stream) to [base]/extract
POSTing file utf8-example.xml (application/xml) to [base]
POSTing file vidcard.xml (application/xml) to [base]
21 files indexed.
COMMITting Solr index changes to http://localhost:8983/solr/techproducts/update...
Time spent: 0:00:02.481

现在我们的 Solr 里已经索引了数据,现在可以开始准备搜索了~

基础检索

Solr 可以通过 REST 客户端、curl、wget、Chrome POSTMAN 等以及可用于多种编程语言的本机客户端进行查询。

Solr Admin UI 包含一个查询构建器界面,通过 techproducts 集合的“查询”选项卡(位于 http://localhost:8983/solr/#/techproducts/query)。
如果单击“Execute Query”按钮而不更改表单中的任何内容,我们将获得 10 个 JSON 格式的文档:
在这里插入图片描述
上图中右上角的浅灰色的连接是我们发送的请求 URL,如果单机它,我们的浏览器会显示原始的响应。

使用 curl 命令如下:

curl "http://localhost:8983/solr/techproducts/select?indent=on&q=*:*"

上面的请求中,我们使用 Solr 的查询参数(q)和特殊语法来请求索引(:)中的所有文档。并不是所有的文档都返回给我们,参数 rows 控制着返回文档的条数,上图中可以看到 rows 被设置了 10。我们可以在 UI 界面更改我们想要修改的参数。

Solr 具有非常强大的搜索选项,本教程无法涵盖所有这些选项。但我们可以涵盖一些最常见的查询类型。

搜索单个 Term

要搜索 Term,我们在搜索页面将更改参数 q 的值,将*:*替换成我们要检索的 Term。

输入 “foundation” 并点击 [Execute Query] 按钮。

如果你想使用 curl 可以输入如下命令:

curl "http://localhost:8983/solr/techproducts/select?q=foundation&rows=1"

我们会得到如下内容:
在这里插入图片描述
响应表明有 4 个命中 (“numFound”:4),我们只在上面的示例输出中包含了一个文档。

注意文档之前的responseHeader,此标题将包含您为搜索设置的参数。默认情况下,它仅显示您为此查询设置的参数。

我们返回的文档包括每个已索引文档的所有字段,这也是默认的行为。如果要限制响应中的字段,可以使用 fl 参数,该参数采用逗号分隔的字段名称列表。这是Admin UI 界面中查询表单上的可用字段之一。

我们将 id 填写到 fl 输入框中,再次执行查询,或在 curl 中明确指定:

curl "http://localhost:8983/solr/techproducts/select?q=foundation&fl=id"

此时应该只能看到返回的匹配记录的 ID。
在这里插入图片描述

字段检索(Field Searches)

所有 Solr 查询都会使用某个字段查找文档。通常,我们希望同时查询多个字段,这就是我们迄今为止在“基础”查询中所做的事情。这可以通过使用复制字段来实现,这些字段已经使用这组配置进行了设置。我们将在练习 2 中更多地介绍复制字段。

但有时,我们希望将查询限制为单个字段。这可以使查询更加高效,并且结果与用户更加相关。

我们的小样本数据集中的大部分数据都与产品相关。假设我们想要查找索引中的所有“electronics”产品。在 q 框中输入“Electronics”并执行查询,我们会得到 14 个结果,如下:
在这里插入图片描述
此搜索会查找索引字段中任何位置包含术语“electronics”的所有文档。但是,我们可以从上面看到有一个 cat 字段(用于“类别”)。如果我们将搜索限制为仅搜索“electronics”类别的文档,那么结果对于我们的用户来说将会更加精确。

更改 q 为 cat: electronics。现在我们得到 12 个结果:
在这里插入图片描述

短语查询(Phrase Search)

要搜索多术语短语,请将其括在双引号中:q="multiple terms here"。例如,我们修改 q 为:“CAS latency”

如果使用curl,请注意术语之间的空格必须转换为URL中的“+”,如下所示:

curl "http://localhost:8983/solr/techproducts/select?q=\"CAS+latency\""

我们将得到 2 个结果:
在这里插入图片描述

组合查询(Combining Searches)

默认情况下,当在单个查询中搜索多个Term and/or 短语时,Solr 将只要求其中之一存在,以便文档匹配。包含更多 Term 的文档将在结果列表中排序得更高。

可以通过在术语或短语前加上 + 前缀来要求其存在;相反,要禁止出现某个术语或短语,请在其前面加上 - 前缀。

要查找同时包含术语“electronics”和“music”的文档,请在“管理 UI 查询”选项卡的 q 中输入 +electronics +music

如果使用curl,则必须对+字符进行编码,因为它在URL中具有保留用途(对空格字符进行编码)。 + 的编码是 %2B,如下所示:

curl "http://localhost:8983/solr/techproducts/select?q=%2Belectronics%20%2Bmusic"

我们应该只会得到单一结果:
在这里插入图片描述
要搜索包含“electronics”但不包含“music”的文档,更改 q 为: + electronics -music。对于curl,再次将URL 编码为%2B,如下所示:

curl "http://localhost:8983/solr/techproducts/select?q=%2Belectronics+-music"

此时我们应该得到 13 个结果:
在这里插入图片描述

更多有关搜索的信息

我们只触及了 Solr 中可用搜索选项的表面。有关更多 Solr 搜索选项,请参阅搜索部分。

练习1 总结

至此,我们已经了解了 Solr 如何索引数据并完成了一些基本查询。如果你现在可以选择继续下一个示例,该示例将介绍更多 Solr 概念,例如分面结果和管理架构,或者你也可以自行解决。

如果想要删除练习中的数据可以执行:bin/solr delete -c techproducts,可以创建新的 collection:bin/solr create -c <yourCollection> -s 2 -rf 2,要停止我们启动的两个 Solr 节点,命令:bin/solr stop -all

有关 bin/solr 的启动/停止和收集选项的更多信息,请参阅 Solr 控制脚本

练习 2:修改架构和索引影片数据

本练习将以上一个练习为基础,并向您介绍索引架构和 Solr 强大的 faceting 功能。

创建一个新的 Collection

我们将在本练习中使用一个全新的数据集,因此最好有一个新的集合,而不是尝试重用之前的数据集。

原因之一是我们将使用 Solr 中称为“字段猜测”的功能,Solr 在索引字段时尝试猜测字段中的数据类型。它还会自动在 schema 中为出现在传入文档中的新字段创建新字段。这种模式称为“Schemaless”。我们将了解这种方法的优点和局限性,帮助你决定在实际应用程序中如何以及在何处使用它。

什么是“Schema”?为什么需要一个?

Solr 的 Schema 是一个单一文件(XML 格式),用于存储有关 Solr 需要理解的字段和字段类型的详细信息。该 Schema 不仅定义字段或字段类型名称,还定义字段在索引之前应发生的任何修改。例如,如果您希望确保输入"abc"的用户和输入"ABC"的用户都能找到包含术语"ABC"的文档,您将希望在索引时将"ABC"标准化(在这种情况下转换为小写),并标准化用户查询以确保匹配。这些规则通常在您的模式(Schema)中定义。

在本教程的前面,我们提到了复制字段,这些字段由源自其他字段的数据组成。您还可以定义动态字段,它使用通配符(例如 *_t 或 *_s)动态创建特定字段类型的字段。这些类型的规则也在 schema 中定义。

当您最初在第一次练习中启动Solr时,我们可以选择要使用的configSet。我们选择的那个configSet具有预定义的模式,适用于我们后来索引的数据。这一次,我们将使用一个具有非常简单模式的configSet,并让Solr根据数据来确定要添加哪些字段。

您要索引的数据与电影相关,因此首先创建一个名为“films”的集合,该集合使用 _default configSet:

bin/solr create -c films -s 2 -rf 2

上面的语句中我们没有指定 configSet,它将使用 _default,如果没有指定默认我们使用的是该配置。
参数 -s 和 -rf 表面了我们创建的 shard 数和副本数。这相当于我们在第一个练习的交互式示例中的选项。如果使用的是 root 账号在命令的最后加上 -force 选项。执行的结果如下:
在这里插入图片描述
该命令打印的第一件事是关于不在生产中使用此 configSet 的警告。
访问 http://localhost:8983/solr/#/films/collection-overview 我们应该会看到概述页面:
在这里插入图片描述

为电影数据准备 Schemaless

_default configSet 附带的模式会发生两个并行的事情。

首先,我们使用“托管模式”(managed schema),它被配置为只能由 Solr 的Schema API 修改。这意味着我们不应该手动编辑它,这样就不会混淆哪些编辑来自哪个来源。Solr 的 Schema API 允许我们更改字段、字段类型和其他类型的架构规则。

其次,我们使用“字段猜测”(field guessing),它在 solrconfig.xml 文件中配置(并且包括 Solr 的大多数各种配置设置)。字段猜测旨在让我们能够在尝试索引文档之前开始使用Solr,而无需定义我们认为文档中会包含的所有字段。这就是为什么我们称之为"无模式"(schemaless),因为您可以快速开始,并在Solr在文档中遇到字段时让其为您创建字段。

这听起来很不错,但是并不是如此,其也有局限性。这有点强制性,如果猜测错误,一旦数据被索引,您就无法对字段进行太多更改,而不必重新索引。如果我们只有几千个文档,这可能还不错,但如果您有数百万甚至数千万个文档,或者更糟糕的是,不再能够访问原始数据,那么这可能会成为一个真正的问题。

由于这些原因,Solr 社区不建议在没有您自己定义的模式的情况下投入生产。无模式功能一开始就很好,但我们仍然应该始终确保我们的模式(Schema)符合对数据索引方式以及用户查询方式的期望。

可以将无模式特性与已定义的模式混合使用。使用模式API,您可以定义一些您知道您想要控制的字段,同时让Solr猜测其他字段,这些字段可能不太重要,或者您有信心(通过测试)可以被猜测到您的满意程度。这就是我们要在这里做的。

创建“names”字段

我们要索引的电影数据包含每部电影的少量字段:ID、导演姓名、电影名称、发行日期和流派。

如果查看example/films,会看到第一个电影名称:.45,发行于 2006。
在这里插入图片描述
作为数据集中的第一个文档,Solr 将根据记录中的数据猜测字段类型。如果我们继续索引这些数据,第一个电影名称将向 Solr 表明该字段类型是“浮点”数字字段,并将创建一个类型为 FloatPointField 的“名称”字段。该记录之后的所有数据预计都是浮点数。

这肯定是行不通的,我们有像 A Mighty Wind 和 Chicken Run 这样的标题,它们是字符串而不是数字,更不是浮点数。如果我们让 Solr 猜测“name”字段是浮点数,那么后面的标题将导致错误并且索引将失败。

我们可以做的是在索引数据之前在 Solr 中设置“name”字段,以确保 Solr 始终将其解释为字符串。

在命令行中输入以下curl命令:

curl -X POST -H 'Content-type:application/json' --data-binary '{"add-field": {"name":"name", "type":"text_general", "multiValued":false, "stored":true}}' http://localhost:8983/solr/films/schema

此命令使用Schema API 显式定义名为“name”的字段,其字段类型为“text_general”(文本字段)。它不允许有多个值,但它将被存储(意味着可以通过查询检索它)。我们还可以使用Admin UI界面 创建字段,但它对字段属性的控制要少一些。不过,它适用于我们的情况:
在这里插入图片描述

创建“catchall”复制字段

在开始索引之前,还需要进行一项更改。在第一次练习中,当我们查询已经索引的文档时,无需指定要搜索的字段,因为我们使用的配置已经设置将字段复制到一个文本字段中,当查询中未定义其他字段时,该字段成为默认字段。

我们现在使用的配置没有默认搜索字段的规则,因此每次查询都需要定义要搜索的字段。不过,我们可以通过定义一个复制字段来设置一个"捕获所有字段",这个复制字段将从所有字段中获取数据并将其索引到一个名为_text_的字段中。现在让我们这样做。

为此,可以使用Admin UI 或Schema API。

在命令行中,再次使用 Schema API 定义复制字段:

curl -X POST -H 'Content-type:application/json' --data-binary '{"add-copy-field" : {"source":"*","dest":"_text_"}}' http://localhost:8983/solr/films/schema

在 Admin UI 界面中,选择 [Add Copy Field] 然后填写字段的源和目标,如下图所示:
在这里插入图片描述
其作用是复制所有字段并将数据放入“text”字段中。

NOTE:
对生产数据执行此操作的成本可能非常高,因为它告诉 Solr 有效地将所有内容索引两次。它会使索引过程变慢,并使索引变大。对于生产数据,需要确保只复制真正适合的应用程序的字段。

现在我们准备好索引数据并开始使用它。

索引样例数据

索引的电影数据位于安装的 example/films 目录中。它提供三种格式:JSON、XML 和 CSV。
选择一种格式并将其索引到“films”集合中(在每个示例中,一个命令适用于 Unix/MacOS,另一个命令适用于 Windows):

  • To Index JSON Format:
    bin/post -c films example/films/films.json

    C:\solr-7.7.0> java -jar -Dc=films -Dauto example\exampledocs\post.jar example\films\*.json
    
  • To Index XML Format
    bin/post -c films example/films/films.xml

    C:\solr-7.7.0> java -jar -Dc=films -Dauto example\exampledocs\post.jar example\films\*.xml
    
  • To Index CSV Format
    bin/post -c films example/films/films.csv -params “f.genre.split=true&f.directed_by.split=true&f.genre.separator=|&f.directed_by.separator=|”

    C:\solr-7.7.0> java -jar -Dc=films -Dparams=f.genre.split=true&f.directed_by.split=true&f.genre.separator=|&f.directed_by.separator=| -Dauto example\exampledocs\post.jar example\films\*.csv
    

每个命令都包含以下主要参数:

  • -c films: 这是用于索引数据的 Solr 集合。
  • example/films/films.json (or films.xml or films.csv): 这是要索引的数据文件的路径。可以简单地提供该文件所在的目录,但由于知道要索引的格式,因此指定该格式的确切文件会更有效。

请注意,CSV 命令包含额外参数。这是为了确保“genre”和“directed_by”列中的多值条目由竖线 (|) 字符分隔,在此文件中用作分隔符。告诉 Solr 以这种方式分割这些列将确保数据的正确索引。每个命令都会产生类似于下面在索引 JSON 时看到的输出:

[root@stackstone-002 solr-7.7.2]# bin/post -c films example/films/films.json
java -classpath /opt/solr/solr-7.7.2/dist/solr-core-7.7.2.jar -Dauto=yes -Dc=films -Ddata=files org.apache.solr.util.SimplePostTool example/films/films.json
SimplePostTool version 5.0.0
Posting files to [base] url http://localhost:8983/solr/films/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
POSTing file films.json (application/json) to [base]/json/docs
1 files indexed.
COMMITting Solr index changes to http://localhost:8983/solr/films/update...
Time spent: 0:00:01.615

http://localhost:8983/solr/#/films/query 中执行查询,此时应该可以看到 1100 条结果。
在这里插入图片描述
让我们进行一个查询,看看“catchall”字段是否正常工作。在 q 框中输入“comedy”,然后再次单击“执行查询”,应该会看到 417 个结果。
在这里插入图片描述

Faceting

Solr中最受欢迎的功能之一是分面(faceting)。分面允许将搜索结果排列成子集(或桶、或类别),为每个子集提供计数。有几种类型的分面:字段值、数值和日期范围、枢轴(决策树)以及任意查询分面。

Field Facets

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

在 Admin UI 界面,如果勾选了 facet 选项,你将看到如下于 facet 的相关选项:
在这里插入图片描述
要查看所有文档的facet计数(q=:):请启用 facet(facet=true),并通过 facet.field 参数指定要进行 facet 计算的字段。如果只需要 facet 计数而不需要文档内容,请指定 rows=0。下面的curl命令将返回genre_str字段的 facet 计数。

curl "http://localhost:8983/solr/films/select?q=*:*&rows=0&facet=true&facet.field=genre_str"

在这里插入图片描述
在 facet_counts 部分中,默认情况下您会看到索引中每个流派使用每种流派的文档数量。Solr 有一个参数 facet.mincount,您可以使用该参数将 facet 限制为仅包含一定数量文档的 facet(此参数未在UI 中显示)。

如果你想控制桶中的项目数量,你可以这样做:

curl "http://localhost:8983/solr/films/select?=&q=*:*&facet.field=genre_str&facet.mincount=200&facet=on&rows=0"

此时只会看到 4 个 facets 的返回。

还有大量其他参数可帮助我们控制 Solr 如何构建 facet 和 facet 列表。详情参阅 Faceting

Range Facets

对于数字或日期,通常需要将 facet 计数划分为范围而不是离散值。使用我们之前练习中的示例 techproducts 数据,数字范围 facet 的一个主要示例是价格。

电影数据包括电影的发行日期,我们可以使用它来创建日期范围 facet,这是范围 facet 的另一种常见用途。

Solr 管理 UI 尚不支持范围方面选项,因此您将需要使用curl或类似的命令行工具来完成以下示例。

curl 'http://localhost:8983/solr/films/select?q=*:*&rows=0&facet=true&facet.range=initial_release_date&facet.range.start=NOW-20YEAR&facet.range.end=NOW&facet.range.gap=%2B1YEAR'

这要求所有电影按从 20 年前开始(我们最早的发行日期是 2000 年)到今天结束的年份进行分组。请注意,此查询 URL 再次将 + 编码为 %2B,结果如下:

[root@stackstone-002 solr-7.7.2]# curl 'http://localhost:8983/solr/films/select?q=*:*&rows=0&facet=true&facet.range=initial_release_date&facet.range.start=NOW-20YEAR&facet.range.end=NOW&facet.range.gap=%2B1YEAR'
{
  "responseHeader":{
    "zkConnected":true,
    "status":0,
    "QTime":42,
    "params":{
      "facet.range":"initial_release_date",
      "q":"*:*",
      "facet.range.gap":"+1YEAR",
      "rows":"0",
      "facet":"true",
      "facet.range.start":"NOW-20YEAR",
      "facet.range.end":"NOW"}},
  "response":{"numFound":1100,"start":0,"maxScore":1.0,"docs":[]
  },
  "facet_counts":{
    "facet_queries":{},
    "facet_fields":{},
    "facet_ranges":{
      "initial_release_date":{
        "counts":[
          "2004-01-03T08:25:44.751Z",165,
          "2005-01-03T08:25:44.751Z",167,
          "2006-01-03T08:25:44.751Z",172,
          "2007-01-03T08:25:44.751Z",45,
          "2008-01-03T08:25:44.751Z",13,
          "2009-01-03T08:25:44.751Z",5,
          "2010-01-03T08:25:44.751Z",1,
          "2011-01-03T08:25:44.751Z",0,
          "2012-01-03T08:25:44.751Z",0,
          "2013-01-03T08:25:44.751Z",2,
          "2014-01-03T08:25:44.751Z",0,
          "2015-01-03T08:25:44.751Z",1,
          "2016-01-03T08:25:44.751Z",0,
          "2017-01-03T08:25:44.751Z",0,
          "2018-01-03T08:25:44.751Z",0,
          "2019-01-03T08:25:44.751Z",0,
          "2020-01-03T08:25:44.751Z",0,
          "2021-01-03T08:25:44.751Z",0,
          "2022-01-03T08:25:44.751Z",0,
          "2023-01-03T08:25:44.751Z",0],
        "gap":"+1YEAR",
        "start":"2004-01-03T08:25:44.751Z",
        "end":"2024-01-03T08:25:44.751Z"}},
    "facet_intervals":{},
    "facet_heatmaps":{}}}

可以在 UI 界面在 Raw Query Parameters 填写相关的请求参数,效果如下:
在这里插入图片描述

Pivot Facets

另一种分面类型是枢轴分面,也称为“决策树”,允许为所有各种可能的组合嵌套两个或多个字段。使用电影数据,数据透视面可用于查看“戏剧”类别(genre_str 字段)中有多少部电影是由导演执导的。以下是获取此场景的原始数据的方法:

curl "http://localhost:8983/solr/films/select?q=*:*&rows=0&facet=on&facet.pivot=genre_str,directed_by_str"

执行效果如下:
在这里插入图片描述

练习 3:索引自己的数据

对于最后一个练习,可以使用自己选择的数据集。这可以是本地硬盘上的文件、你之前使用过的一组数据,也可能是你打算为生产应用程序索引到 Solr 的数据样本。

索引方法

Local Files with bin/post

如果您有本地文件目录,则发布工具 (bin/post) 可以索引文件目录。我们在第一次练习中看到了这一点。

我们在练习中仅使用 JSON、XML 和 CSV,但 Post Tool 还可以处理 HTML、PDF、Microsoft Office 格式(例如 MS Word)、纯文本等。

在本例中,假设本地有一个名为“Documents”的目录。为了对其进行索引,我们将发出这样的命令(根据需要更正 -c 参数后面的集合名称):

./bin/post -c localDocs ~/Documents

在处理文档时,可能会遇到错误。这些错误可能是由字段猜测引起的,或者与文件类型不受支持有关。索引此类内容需要为我们依据数据来规划Solr,这需要理解数据,并可能需要一些试错过程。

DataImportHandler

Solr 包括一个称为数据导入处理程序 (DIH) 的工具,它可以连接到数据库(如果您有 jdbc 驱动程序)、邮件服务器或其他结构化数据源。

example/example-DIH 中的 README.txt 文件将为您提供有关如何开始使用此工具的详细信息。

SolrJ

SolrJ 是一个基于 Java 的客户端,用于与 Solr 交互。使用适用于基于 JVM 的语言的 SolrJ 或其他 Solr 客户端以编程方式创建要发送到 Solr 的文档。

Documents Screen

使用“管理 UI 文档”选项(位于 http://localhost:8983/solr/#/localDocs/documents)粘贴要索引的文档,或从 Document Type 下拉列表中选择 Document Builder 逐个字段构建文档。最后,单机表单下方的 Submit Document 按钮来索引您的文档。

更新数据

您可能会注意到,即使您多次索引本教程中的内容,它也不会重复找到的结果。这是因为示例 Solr schema(名为 Managed-Schema 或 schema.xml 的文件)指定了一个名为 id 的 uniqueKey 字段。每当您向 Solr POST 命令添加一个与现有文档具有相同 uniqueKey 值的文档时,它会自动为您替换它。

通过查看 Solr 管理页面的特定于核心的概述部分中的 numDocs 和 maxDoc 的值,您可以看到已经发生了这种情况。

numDocs 表示索引中可搜索文档的数量(并且将大于 XML、JSON 或 CSV 文件的数量,因为某些文件包含多个文档)。maxDoc 值可能会更大,因为 maxDoc 计数包括尚未从索引中物理删除的逻辑删除文档。您可以根据需要一遍又一遍地重新发布示例文件,并且 numDocs 永远不会增加,因为新文档将不断替换旧文档。

继续编辑任何现有示例数据文件,更改一些数据,然后重新运行 PostTool (bin/post)。你将可以看到更改反映在后续搜索中。

删除数据

如果您需要迭代几次才能获得正确的 schema,您可能需要删除文档以清除集合,然后重试。但请注意,仅删除文档不会更改基础字段定义。从本质上讲,这将允许您在根据需要更改字段后重新索引数据。

您可以通过将删除命令发布到更新 URL 并指定文档的唯一键字段的值或匹配多个文档的查询来删除数据。如果我们正确构造请求,我们也可以使用 bin/post 来删除文档。

执行以下命令删除特定文档:

bin/post -c localDocs -d "<delete><id>SP2514N</id></delete>"

要删除所有文档,您可以使用“delete-by-query”命令,例如:

bin/post -c localDocs -d "<delete><query>*:*</query></delete>"

您还可以修改上述内容以仅删除与特定查询匹配的文档。

空间查询(Spatial Queries)

Solr 具有复杂的地理空间支持,包括在给定位置的指定距离范围内(或边界框内)进行搜索、按距离排序,甚至按距离增强结果。

我们在练习 1 中索引的一些示例技术产品文档具有与其关联的位置,以说明空间功能。

空间查询可以与任何其他类型的查询相结合,例如在距旧金山 10 公里范围内查询“ipod”的示例中:
在这里插入图片描述
了解更多关于 Solr 空间搜索请参阅 Spatial Search


参考:
https://solr.apache.org/guide/7_7/solr-tutorial.html#spatial-queries

1 概述 4 1.1 企业搜索引擎方案选型 4 1.2 Solr的特性 4 1.2.1 Solr使用Lucene并且进行了扩展 4 1.2.2 Schema(模式) 5 1.2.3 查询 5 1.2.4 核心 5 1.2.5 缓存 5 1.2.6 复制 6 1.2.7 管理接口 6 1.3 Solr服务原理 6 1.3.1 索引 6 1.3.2 搜索 7 1.4 源码结构 8 1.4.1 目录结构说明 8 1.4.2 Solr home说明 9 1.4.3 solr的各包的说明 10 1.5 版本说明 11 1.5.1 1.3版本 11 1.5.2 1.4版本 12 1.6 分布式和复制 Solr 架构 13 2 Solr的安装与配置 13 2.1 在Tomcat下Solr安装 13 2.1.1 安装准备 13 2.1.2 安装过程 14 2.1.3 验证安装 15 2.2 中文分词配置 15 2.2.1 mmseg4j 15 2.2.2 paoding 19 2.3 多核(MultiCore)配置 22 2.3.1 MultiCore的配置方法 22 2.3.2 为何使用多core ? 23 2.4 配置文件说明 23 2.4.1 schema.xml 24 2.4.2 solrconfig.xml 25 3 Solr的应用 29 3.1 SOLR应用概述 29 3.1.1 Solr的应用模式 29 3.1.2 SOLR的使用过程说明 30 3.2 一个简单的例子 30 3.2.1 Solr Schema 设计 30 3.2.2 构建索引 30 3.2.3 搜索测试 31 3.3 搜索引擎的规划设计 32 3.3.1 定义业务模型 32 3.3.2 定制索引服务 34 3.3.3 定制搜索服务 34 3.4 搜索引擎配置 34 3.4.1 Solr Schema 设计(如何定制索引的结构?) 34 3.5 如何进行索引操作? 36 3.5.1 基本索引操作 36 3.5.2 批量索引操作 37 3.6 如何进行搜索 39 3.6.1 搜索语法 39 3.6.2 排序 42 3.6.3 字段增加权重 42 3.6.4 Solr分词器、过滤器、分析器 42 3.6.5 Solr高亮使用 46 4 SolrJ的用法 46 4.1 搜索接口的调用实例 46 4.2 Solrj的使用说明 47 4.2.1 Adding Data to Solr 47 4.2.2 Directly adding POJOs to Solr 49 4.2.3 Reading Data from Solr 51 4.3 创建查询 51 4.4 使用 SolrJ 创建索引 52 4.5 Solrj包的结构说明 53 4.5.1 CommonsHttpSolrServer 53 4.5.2 Setting XMLResponseParser 53 4.5.3 Changing other Connection Settings 53 4.5.4 EmbeddedSolrServer 54 5 Solr的实际应用测试报告 54 5.1 线下压力测试报告 54 5.2 线上环境运行报告 54 6 solr性能调优 55 6.1 Schema Design Considerations 55 6.1.1 indexed fields 55 6.1.2 stored fields 55 6.2 Configuration Considerations 55 6.2.1 mergeFactor 55 6.2.2 mergeFactor Tradeoffs 56 6.3 Cache autoWarm Count Considerations 56 6.4 Cache hit rate(缓存命中率) 56 6.5 Explicit Warming of Sort Fields 56 6.6 Optimization Considerations 56 6.7 Updates and Commit Frequency Tradeoffs 56 6.8 Query Response Compression 57 6.9 Embedded vs HTTP Post 57 6.10 RAM Usage Considerations(内存方面的考虑) 57 6.10.1 OutOfMemoryErrors 57 6.10.2 Memory allocated to the Java VM 57 7 FAQ 58 7.1 出现乱码或者查不到结果的排查方法: 58
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Stack Stone

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值