托管资源

托管资源公开一个 REST API 端点,用于对 Solr 对象执行创建-读取-更新-删除 (CRUD) 操作。

任何具有配置设置和/或数据的长期存在的 Solr 对象都是托管资源的良好候选者。托管资源补充了 Solr 中其他可通过编程方式管理的组件,例如使用 RESTful 模式 API 向托管模式添加字段。

考虑一个基于 Web 的 UI,它提供 Solr 即服务,其中用户需要配置一组停用词和同义词映射作为其搜索应用程序初始设置过程的一部分。这种类型的用例可以使用 Solr 提供的托管停用词过滤器和托管同义词图过滤器工厂,通过托管资源 REST API 轻松支持。

用户还可以编写自己的自定义插件,利用相同的内部钩子来使其他资源受 REST 管理。

本节中的所有示例都假定您正在运行 "techproducts" Solr 示例

bin/solr start -e techproducts

托管资源概述

让我们首先了解一下托管资源,方法是查看 Solr 提供的一些使用 REST API 管理停用词和同义词的示例。阅读完本节后,您将准备好深入了解托管资源如何在 Solr 中实现的细节,以便您可以开始构建自己的实现。

管理停用词

首先,您需要定义一个使用 ManagedStopFilterFactory 的字段类型,例如

<fieldType name="managed_en" positionIncrementGap="100">
  <analyzer>
    <tokenizer class="solr.StandardTokenizerFactory"/>
    <filter class="solr.ManagedStopFilterFactory" (1)
            managed="english" /> (2)
  </analyzer>
</fieldType>

关于此字段类型定义,有两点需要注意

1 过滤器实现类是 solr.ManagedStopFilterFactory。这是 StopFilterFactory 的特殊实现,它使用一组通过 REST API 管理的停用词。
2 managed=”english” 属性为一组托管停用词命名,在本例中,表示停用词用于英文文本。

用于管理 techproducts 集合中英语停用词的 REST 端点是:/solr/techproducts/schema/analysis/stopwords/english

示例资源路径应该是不言自明的。应该注意的是,ManagedStopFilterFactory 实现确定了路径的 /schema/analysis/stopwords 部分,这是有道理的,因为这是由模式定义的分析组件。

由此可见,使用以下过滤器的字段类型

<filter class="solr.ManagedStopFilterFactory"
        managed="french" />

将解析为路径:/solr/techproducts/schema/analysis/stopwords/french

现在让我们看看这个 API 的实际应用,从一个简单的 GET 请求开始

curl "https://127.0.0.1:8983/solr/techproducts/schema/analysis/stopwords/english"

假设您将此请求发送到 Solr,则响应正文是一个 JSON 文档

{
  "responseHeader":{
    "status":0,
    "QTime":1
  },
  "wordSet":{
    "initArgs":{"ignoreCase":true},
    "initializedOn":"2014-03-28T20:53:53.058Z",
    "managedList":[
      "a",
      "an",
      "and",
      "are",
       ]
  }
}

sample_techproducts_configs configset 附带一组预先构建的托管停用词,但是您应该仅使用 API 与此文件进行交互,而不要直接编辑它。

在此响应中,您应该注意到的一件事是它包含一个单词的 managedList 以及 initArgs。这是此框架中的一个重要概念 - 托管资源通常具有配置和数据。对于停用词,唯一的配置参数是一个布尔值,用于确定在停用词过滤期间是否忽略标记的大小写(ignoreCase=true|false)。数据是一个单词列表,它在响应中表示为名为 managedList 的 JSON 数组。

现在,让我们使用 HTTP PUT 将一个新单词添加到英语停用词列表

curl -X PUT -H 'Content-type:application/json' --data-binary '["foo"]' "https://127.0.0.1:8983/solr/techproducts/schema/analysis/stopwords/english"

这里我们使用 curl 将包含单个单词 "foo" 的 JSON 列表 PUT 到托管的英语停用词集中。如果请求成功,Solr 将返回 200。您还可以在单个 PUT 请求中放入多个单词。

您可以通过发送针对该单词的 GET 请求,作为集合的子资源来测试特定单词是否存在,例如:

curl "https://127.0.0.1:8983/solr/techproducts/schema/analysis/stopwords/english/foo"

如果子资源(foo)存在,此请求将返回状态码 200;如果受管理的列表中不存在该子资源,则返回状态码 404。

要删除停用词,您需要执行以下操作:

curl -X DELETE "https://127.0.0.1:8983/solr/techproducts/schema/analysis/stopwords/english/foo"
PUT/POST 用于向现有列表添加术语,而不是完全替换列表。这是因为向现有列表添加术语比完全替换列表更常见,因此 API 倾向于采用更常用的增量添加术语的方法,尤其是在也支持删除单个术语的情况下。

管理同义词

在大多数情况下,用于管理同义词的 API 与用于管理停用词的 API 类似,只是它不是使用单词列表,而是使用映射,其中映射中每个条目的值是术语的一组同义词。与停用词一样,sample_techproducts_configs 配置集包含一组预构建的同义词映射,适用于通过以下字段类型定义激活的示例数据:

<fieldType name="managed_en" positionIncrementGap="100">
  <analyzer type="index">
    <tokenizer class="solr.StandardTokenizerFactory"/>
    <filter class="solr.ManagedStopFilterFactory" managed="english" />
    <filter class="solr.ManagedSynonymGraphFilterFactory" managed="english" />
    <filter class="solr.FlattenGraphFilterFactory"/> <!-- required on index analyzers after graph filters -->
  </analyzer>
  <analyzer type="query">
    <tokenizer class="solr.StandardTokenizerFactory"/>
    <filter class="solr.ManagedStopFilterFactory" managed="english" />
    <filter class="solr.ManagedSynonymGraphFilterFactory" managed="english" />
  </analyzer>
</fieldType>

要获取受管理的同义词映射,请向以下地址发送 GET 请求:

curl "https://127.0.0.1:8983/solr/techproducts/schema/analysis/synonyms/english"

此请求将返回如下所示的响应:

{
  "responseHeader":{
    "status":0,
    "QTime":3},
  "synonymMappings":{
    "initArgs":{
      "ignoreCase":true,
      "format":"solr"},
    "initializedOn":"2014-12-16T22:44:05.33Z",
    "managedMap":{
      "GB":
        ["GiB",
         "Gigabyte"],
      "TV":
        ["Television"],
      "happy":
        ["glad",
         "joyful"]}}}

受管理的同义词在 managedMap 属性下返回,其中包含一个 JSON 映射,其中每个条目的值是术语的一组同义词,例如,在上面的示例中,“happy” 的同义词是“glad”和“joyful”。

要添加新的同义词映射,您可以 PUT/POST 单个映射,例如:

curl -X PUT -H 'Content-type:application/json' --data-binary '{"mad":["angry","upset"]}' "https://127.0.0.1:8983/solr/techproducts/schema/analysis/synonyms/english"

如果 PUT 请求成功,API 将返回状态码 200。要确定特定术语的同义词,您可以发送针对子资源的 GET 请求,例如 /schema/analysis/synonyms/english/mad 将返回 ["angry","upset"]

您还可以 PUT 对称同义词列表,该列表将被扩展为列表中每个术语的映射。例如,您可以使用 JSON 列表语法而不是映射来 PUT 以下对称同义词列表:

curl -X PUT -H 'Content-type:application/json' --data-binary '["funny", "entertaining", "whimiscal", "jocular"]' "https://127.0.0.1:8983/solr/techproducts/schema/analysis/synonyms/english"

请注意,扩展是在处理 PUT 请求时执行的,因此底层的持久状态仍然是受管理的映射。因此,如果在发送上一个 PUT 请求后,您对 /schema/analysis/synonyms/english/jocular 执行了 GET 请求,那么您将收到一个包含 ["funny", "entertaining", "whimiscal"] 的列表。使用列表创建同义词映射后,每个术语都必须单独管理。

最后,您可以通过向受管理的端点发送 DELETE 请求来删除映射。

应用受管理资源更改

通过此 REST API 对受管理资源所做的更改不会应用于活动的 Solr 组件,直到重新加载 Solr 集合(或单服务器模式下的 Solr Core)。

例如:在添加或删除停用词后,您必须重新加载 Core/集合,更改才会生效;相关 API:CoreAdmin APICollections API

在分布式模式下运行时,需要使用这种方法,以确保更改同时应用于集合中的所有 Core,从而使行为一致且可预测。不言而喻,您不希望其中一个副本使用与其他副本不同的停用词或同义词集。

这种“在重新加载时应用更改”方法的一个细微结果是,一旦使用 API 进行更改,就没有办法读取活动数据。换句话说,API 从 API 的角度返回最新数据,这可能与 Solr 组件当前正在使用的数据不同。

但是,此 API 实现的意图是,在进行更改后的短时间内通过重新加载应用更改,因此 API 返回的数据与服务器中活动数据不同的时间应该是可以忽略不计的。

如果索引时分析器正在使用停用词和同义词映射之类的更改,则通常需要重新索引现有文档。RestManager 框架不会阻止您这样做,它只是使您能够以编程方式构建一组停用词、同义词等。有关重新索引文档的更多信息,请参阅 重新索引 部分。

RestManager 端点

可以使用每个集合的 /schema/managed 端点获取有关已注册的 ManagedResources 的元数据。

假设您的架构中定义了上面显示的 managed_en 字段类型,则向以下资源发送 GET 请求将返回有关哪些与架构相关的资源由 RestManager 管理的元数据:

curl "https://127.0.0.1:8983/solr/techproducts/schema/managed"

响应主体是一个 JSON 文档,其中包含 /schema 根目录下受管理资源的元数据。

{
  "responseHeader":{
    "status":0,
    "QTime":3
  },
  "managedResources":[
    {
      "resourceId":"/schema/analysis/stopwords/english",
      "class":"org.apache.solr.rest.schema.analysis.ManagedWordSetResource",
      "numObservers":"1"
    },
    {
      "resourceId":"/schema/analysis/synonyms/english",
      "class":"org.apache.solr.rest.schema.analysis.ManagedSynonymGraphFilterFactory$SynonymManager",
      "numObservers":"1"
    }
  ]
}

您还可以使用 PUT/POST 到相应的 URL 来创建新的受管理资源,甚至在配置使用这些资源的任何内容之前。

例如,假设我们想构建一组德语停用词。在开始添加停用词之前,我们需要创建端点:

/solr/techproducts/schema/analysis/stopwords/german

要创建此端点,请向我们希望创建的端点发送以下 PUT/POST 请求:

curl -X PUT -H 'Content-type:application/json' --data-binary \
'{"class":"org.apache.solr.rest.schema.analysis.ManagedWordSetResource"}' \
"https://127.0.0.1:8983/solr/techproducts/schema/analysis/stopwords/german"

如果请求成功,Solr 将响应状态码 200。实际上,此操作会在 RestManager 中注册一个新的受管理资源端点。从这里开始,您可以开始添加德语停用词,就像我们上面看到的那样。

curl -X PUT -H 'Content-type:application/json' --data-binary '["die"]' \
"https://127.0.0.1:8983/solr/techproducts/schema/analysis/stopwords/german"

对于大多数用户来说,以这种方式创建资源应该永远不是必要的,因为在配置时会自动创建受管理资源。

但是,如果 Solr 组件不再使用受管理资源,您可能需要显式删除它们。

例如,我们可以删除上面创建的德语的受管理资源,因为没有 Solr 组件正在使用它,而不能删除英语停用词的受管理资源,因为架构中声明了一个正在使用它的令牌过滤器。

curl -X DELETE "https://127.0.0.1:8983/solr/techproducts/schema/analysis/stopwords/german"