外部文件和进程

Solr 支持使用名为 ExternalFileFieldType 的字段类型将字段值存储在外部文件中。它还可以使用名为 PreAnalyzedFieldType 的字段类型使用已经经过分析的标记流。

ExternalFileField 类型

ExternalFileField 类型可以指定 Solr 索引外部文件中的字段值。对于此类字段,文件包含从键字段到字段值的映射。另一种思考方式是,Solr 不会在文档编入索引时指定其中的字段,而是从外部文件中查找此字段的值。

外部字段不可搜索。它们只能用于函数查询或显示。有关函数查询的更多信息,请参阅 函数查询 部分。

ExternalFileField 类型适用于以下情况:您希望比更新文档的其余部分更频繁地更新许多文档中的特定字段。例如,假设您已根据视图数量实施了文档排名。您可能希望每天或每小时更新所有文档的排名,而文档的其余内容可能更新频率低得多。如果没有 ExternalFileField,您需要更新每个文档才能更改排名。使用 ExternalFileField 的效率更高,因为特定字段的所有文档值都存储在外部文件中,可以根据需要频繁地更新该文件。

模式 中,此字段类型的定义可能如下所示

<fieldType name="entryRankFile" keyField="pkId" defVal="0" stored="false" indexed="false" class="solr.ExternalFileField"/>

keyField 属性定义将在外部文件中定义的键。它通常是索引的唯一键,但只要 keyField 可用于标识索引中的文档,它不需要那么长。defVal 定义一个默认值,如果外部文件中没有特定文档的条目,将使用该默认值。

外部文件的格式

该文件本身位于 Solr 的索引目录中,默认情况下为 $SOLR_HOME/data。该文件的名称应为 external_fieldnameexternal_fieldname.*。对于上述示例,该文件可以命名为 external_entryRankFileexternal_entryRankFile.txt

如果出现使用名称模式 .*(例如 .txt)的任何文件,则将使用最后一个(按名称排序后)文件,并且将删除以前的版本。此行为支持在可能无法覆盖文件(例如,在 Windows 上,如果文件正在使用)的系统上的实现。

该文件包含将等号左边的键字段映射到右边的值的条目。以下是一些示例条目

doc33=1.414
doc34=3.14159
doc40=42

此文件中列出的键不必唯一。该文件不必排序,但如果排序,Solr 将能够更快地执行查找。

重新加载外部文件

可以定义一个事件侦听器,以便在重新加载搜索器或启动新搜索器时重新加载外部文件。有关更多信息,请参阅 与查询相关的侦听器 部分,但 solrconfig.xml 中的示例定义可能如下所示

<listener event="newSearcher" class="org.apache.solr.schema.ExternalFileFieldReloader"/>
<listener event="firstSearcher" class="org.apache.solr.schema.ExternalFileFieldReloader"/>

PreAnalyzedField 类型

PreAnalyzedField 类型提供了一种将序列化标记流发送到 Solr 的方法,可以选择使用字段的独立存储值,并且可以在 Solr 中存储和索引此信息,而无需应用任何其他文本处理。如果用户希望提交已由某些现有外部文本处理管道(例如,它已标记化、注释、词干、插入同义词等)处理的字段内容,同时使用 Lucene 的 TokenStream 提供的所有丰富属性(每个标记属性),则此方法非常有用。

序列化格式可以使用 PreAnalyzedParser 接口的实现进行插入。有两种开箱即用的实现

  • JsonPreAnalyzedParser:顾名思义,它解析使用 JSON 表示字段内容的内容。如果未对字段类型进行其他配置,则这是要使用的默认解析器。

  • SimplePreAnalyzedParser:使用简单的严格纯文本格式,在某些情况下可能比 JSON 更容易创建。

只有一个配置参数,parserImpl。此参数的值应为实现 PreAnalyzedParser 接口的类的完全限定类名。此参数的默认值为 org.apache.solr.schema.JsonPreAnalyzedParser

默认情况下,此类型的字段的查询时分析器将与索引时分析器相同,它需要序列化的预分析文本。您必须向 fieldType 中添加查询类型分析器,才能对非预分析查询执行分析。在以下示例中,索引时分析器需要默认的 JSON 序列化格式,而查询时分析器将采用 StandardTokenizer/LowerCaseFilter

<fieldType name="pre_with_query_analyzer" class="solr.PreAnalyzedField">
  <analyzer type="query">
    <tokenizer class="solr.StandardTokenizerFactory"/>
    <filter class="solr.LowerCaseFilterFactory"/>
  </analyzer>
</fieldType>

JsonPreAnalyzedParser

这是 PreAnalyzedField 类型使用的默认序列化格式。它使用具有以下键的顶级 JSON 映射

说明 必需

v

版本键。当前支持的版本为 1

必需

str

字段的存储字符串值。您最多可以使用 strbin 中的一个。

可选

bin

字段的存储二进制值。二进制值必须经过 Base64 编码。

可选

tokens

序列化的标记流。这是一个 JSON 列表。

可选

任何其他顶级键都会被静默忽略。

标记流序列化

标记流表示为 JSON 映射的 JSON 列表。每个标记的映射包含以下键和值

说明 Lucene 属性 必需?

t

标记

CharTermAttribute

表示当前标记的 UTF-8 字符串

必需

s

开始偏移量

OffsetAttribute

非负整数

可选

e

结束偏移量

OffsetAttribute

非负整数

可选

i

位置增量

PositionIncrementAttribute

非负整数 - 默认值为 1

可选

p

有效负载

PayloadAttribute

Base64 编码的有效负载

可选

y

词法类型

TypeAttribute

UTF-8 字符串

可选

f

标志

FlagsAttribute

表示十六进制格式的整数值的字符串

可选

任何其他键都会被静默忽略。

JsonPreAnalyzedParser 示例

{
  "v":"1",
  "str":"test ąćęłńóśźż",
  "tokens": [
    {"t":"two","s":5,"e":8,"i":1,"y":"word"},
    {"t":"three","s":20,"e":22,"i":1,"y":"foobar"},
    {"t":"one","s":123,"e":128,"i":22,"p":"DQ4KDQsODg8=","y":"word"}
  ]
}

SimplePreAnalyzedParser

在通过 parserImpl 配置参数指定此格式时要使用的完全限定类名称是 org.apache.solr.schema.SimplePreAnalyzedParser

SimplePreAnalyzedParser 语法

此解析器支持的序列化格式如下

序列化格式
content ::= version (stored)? tokens
version ::= digit+ " "
; stored field value - any "=" inside must be escaped!
stored ::= "=" text "="
tokens ::= (token ((" ") + token)*)*
token ::= text ("," attrib)*
attrib ::= name '=' value
name ::= text
value ::= text

可以使用转义字符 \ 转义“text”值中的特殊字符。识别以下转义序列

转义序列 说明

\

文本空格字符

\,

文本 , 字符

\=

文本 = 字符

\\

文本 \ 字符

\n

换行符

\r

回车

\t

水平制表符

请注意,不支持 Unicode 序列(例如 \u0001)。

支持的属性

支持以下标记属性,并用简短的符号名称标识

名称 说明 Lucene 属性 值格式

i

位置增量

PositionIncrementAttribute

整数

s

开始偏移量

OffsetAttribute

整数

e

结束偏移量

OffsetAttribute

整数

y

词法类型

TypeAttribute

字符串

f

标志

FlagsAttribute

十六进制整数

p

有效负载

PayloadAttribute

十六进制格式的字节;忽略空格

跟踪标记位置并隐式将其添加到标记流中 - 开始和结束偏移量仅考虑术语文本和空格,不包括标记属性占用的空间。

示例标记流

1 one two three
  • 版本:1

  • 存储:null

  • 标记:(term=one,startOffset=0,endOffset=3)

  • 标记:(term=two,startOffset=4,endOffset=7)

  • 标记:(term=three,startOffset=8,endOffset=13)

1 one  two    three
  • 版本:1

  • 存储:null

  • 标记:(term=one,startOffset=0,endOffset=3)

  • 标记:(term=two,startOffset=5,endOffset=8)

  • 标记:(term=three,startOffset=11,endOffset=16)

1 one,s=123,e=128,i=22 two three,s=20,e=22
  • 版本:1

  • 存储:null

  • 标记:(term=one,positionIncrement=22,startOffset=123,endOffset=128)

  • 标记:(term=two,positionIncrement=1,startOffset=5,endOffset=8)

  • 标记:(term=three,positionIncrement=1,startOffset=20,endOffset=22)

1 \ one\ \,,i=22,a=\, two\=

\n,\ =\ \
  • 版本:1

  • 存储:null

  • 标记:(term=one ,,positionIncrement=22,startOffset=0,endOffset=6)

  • 标记:(term=two= ,positionIncrement=1,startOffset=7,endOffset=15)

  • 标记:(term=\,positionIncrement=1,startOffset=17,endOffset=18)

请注意,忽略未知属性及其值,因此在此示例中,第一个标记上的“a”属性和第二个标记上的“ ”(转义空格)属性及其值将被忽略,因为它们不在支持的属性名称中。

1 ,i=22 ,i=33,s=2,e=20 ,
  • 版本:1

  • 存储:null

  • 标记:(term=,positionIncrement=22,startOffset=0,endOffset=0)

  • 标记:(term=,positionIncrement=33,startOffset=2,endOffset=20)

  • 标记:(term=,positionIncrement=1,startOffset=2,endOffset=2)

1 =This is the stored part with \=
\n \t escapes.=one two three
  • 版本:1

  • 存储:This is the stored part with = \t escapes.

  • 标记:(term=one,startOffset=0,endOffset=3)

  • 标记:(term=two,startOffset=4,endOffset=7)

  • 标记:(term=three,startOffset=8,endOffset=13)

请注意,上面存储的值中的 \t 不是文本;以这种方式显示它是为了直观地指示存储的值中的实际制表符。

1 ==
  • 版本:1

  • 存储:""

  • (无标记)

1 =this is a test.=
  • 版本:1

  • 存储:this is a test.

  • (无标记)