托管资源

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

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

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

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

本节中的所有示例均假定您正在运行“techproducts”Solr 示例

bin/solr -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 "http://localhost: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"]' "http://localhost:8983/solr/techproducts/schema/analysis/stopwords/english"

这里我们使用 curl 将包含单个单词“foo”的 JSON 列表 PUT 到受管英语停用词集中。如果请求成功,Solr 将返回 200。你也可以在单个 PUT 请求中放置多个单词。

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

curl "http://localhost:8983/solr/techproducts/schema/analysis/stopwords/english/foo"

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

要删除停用词,你可以执行

curl -X DELETE "http://localhost:8983/solr/techproducts/schema/analysis/stopwords/english/foo"
PUT/POST 用于向现有列表添加术语,而不是完全替换该列表。这是因为向现有列表添加术语比完全替换列表更常见,因此 API 倾向于更常见的方法,即逐步添加术语,特别是由于它还支持删除单个术语。

管理同义词

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

<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 "http://localhost: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"]}' "http://localhost: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"]' "http://localhost:8983/solr/techproducts/schema/analysis/synonyms/english"

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

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

应用受管资源更改

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

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

在分布式模式下运行时需要此方法,这样我们才能确保同时对集合中的所有核心应用更改,以便行为一致且可预测。不用说,您不希望您的某个副本使用与其他副本不同的停用词或同义词集。

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

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

如果索引时分析器使用,则更改停用词和同义词映射等内容通常需要对现有文档重新建立索引。RestManager 框架不会保护您免受此影响,它只是使以编程方式建立一组停用词、同义词等成为可能。有关重新建立文档索引的更多信息,请参阅重新建立索引部分。

RestManager 端点

有关每个集合的已注册 ManagedResources 的元数据可通过 /schema/managed 端点获得。

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

curl "http://localhost: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"}' \
"http://localhost:8983/solr/techproducts/schema/analysis/stopwords/german"

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

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

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

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

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

curl -X DELETE "http://localhost:8983/solr/techproducts/schema/analysis/stopwords/german"