标记器处理器
标记器请求处理程序,又名“SolrTextTagger”,是一个“文本标记器”。
给定一个具有类似名称字段的字典(Solr 索引),您可以将文本发布到此请求处理程序,它将返回每个出现的名称,其中包含偏移量和其他所需的文档元数据。它用于命名实体识别 (NER)。
标记器不进行任何自然语言处理 (NLP)(Lucene 文本分析除外),因此它被认为是“朴素的标记器”,但它绝对可以直接使用,并且可以使用它作为关键组件构建更完整的 NER 或 ERD(实体识别和消除歧义)系统。SolrTextTagger 也可以用于查询以进行查询理解或大型文档。
要了解如何使用它,请跳转到下面的教程。
标记器请求处理程序尚不支持分片索引。它可以在以 SolrCloud 模式运行的集群中使用,但存储标记字典的集合必须是单分片集合。尽管有此限制,但可以支持数千万到数亿个名称(文档);最大值主要受内存限制。
标记器配置
要配置标记器,您的 Solr 模式需要 2 个字段
文本字段的索引分析链,除了需要在末尾使用 ConcatenateGraphFilterFactory
之外,还可以具有适合您的匹配首选项的任何分词器和过滤器。它可以有多词同义词,并使用 WordDelimiterGraphFilterFactory
例如。但是,请不要使用 FlattenGraphFilterFactory
,因为它会干扰 ConcatenateGraphFilterFactory
。位置间隙(例如,停用词)将被忽略;(目前)不支持使间隙变得重要。
另一方面,文本字段的查询分析链则更受限制。同一位置不应存在标记,因此不存在同义词扩展 — 请改为在索引时执行此操作。支持停用词(或任何其他引入位置间隙的过滤器)。在运行时,可以将标记器配置为将其视为标记中断或忽略它。
您的 solrconfig.xml
需要定义 solr.TagRequestHandler
,它像搜索处理程序一样支持 defaults
、invariants
和 appends
部分。
有关配置示例,请跳转到下面的教程。
标记器参数
可以使用请求参数完全配置标记器的执行。只需要 field
。
field
-
必需
默认值:无
用作字典的标记字段。这是必需的;您可能会在请求处理程序中指定它。
fq
-
可选
默认值:无
您可以指定一些过滤器查询来限制用于标记的字典。此参数与
solr.SearchHandler
使用的参数相同。 rows
-
可选
默认值:
10000
要返回的最大文档数。此参数与
solr.SearchHandler
使用的参数相同。 fl
-
可选
默认值:无
Solr 用于列出要返回字段的标准参数。此参数与
solr.SearchHandler
使用的参数相同。 overlaps
-
可选
默认值:
NO_SUB
选择用于确定重叠集合中哪些标签应该保留,哪些应该被修剪的算法。选项有:
-
ALL
:发出所有标签。 -
NO_SUB
:不发出完全包含在另一个标签内的标签(即,没有子标签)。 -
LONGEST_DOMINANT_RIGHT
:给定一个重叠标签的集群,发出最长的标签(按字符长度)。如果长度相同,则选择最右边的标签。删除与此标签重叠的任何标签,然后重复该算法以查找可能在该集群中发出的其他标签。
-
matchText
-
可选
默认值:
false
如果为
true
,则在标签响应中返回匹配的文本。这将触发标签器在标记之前完全缓冲输入。 tagsLimit
-
可选
默认值:
1000
响应中返回的最大标签数量。在此点之后,标记将有效地停止。
skipAltTokens
-
可选
默认值:
false
如果为
true
,则抑制可能发生的错误,例如,如果您在分析器中启用查询时的同义词扩展(通常不应该这样做)。除非您知道无法避免此类标记,否则请将其默认为false
。 ignoreStopwords
-
可选
默认值:
false
一个布尔标志,使停用词(或任何导致位置跳过的条件,如 >255 个字符的单词)被忽略,就像它们不存在一样。否则,其行为是将它们视为标记中的中断,假设您的索引文本分析配置没有定义
StopWordFilter
。默认情况下,将检查索引分析链中是否存在StopWordFilter
,如果找到,则当未指定时ignoreStopWords
为 true。您可能不应该配置StopWordFilter
,并且可能也不需要设置此参数。 xmlOffsetAdjust
-
可选
默认值:
false
如果为
true
,则表示输入是 XML,并且返回标签的偏移量应根据需要进行调整,以允许客户端在标签偏移量对处插入开始和结束元素。如果无法执行此操作,则将省略该标签。当使用此选项时,您应该在 schema 中配置HTMLStripCharFilterFactory
。这将触发标签器在标记之前完全缓冲输入。
Solr 用于控制响应格式的参数也受支持,例如 echoParams
、wt
、indent
等。
使用 Geonames 的教程
这是一个演示如何使用流行的 Geonames 数据集配置和使用文本标签器的教程。它不仅仅是一个教程;它是一个包含上述未描述信息的指南。
创建和配置 Solr 集合
创建一个名为 "geonames" 的 Solr 集合。在本教程中,我们假设使用默认的 "data-driven" 配置。它非常适合实验和快速入门,但不适合生产或优化。
bin/solr create -c geonames
配置标签器
我们需要首先配置 schema。"data driven" 模式允许我们将此步骤保持在最低限度 - 我们只需要声明一个字段类型、2 个字段和一个复制字段。
最关键的部分是预先定义 “tag” 字段类型。有很多方法可以配置文本分析;我们在这里不讨论这些选择。但重要的一点是索引分析器链末尾的 ConcatenateGraphFilterFactory
。另一个重要的性能要素是 postingsFormat=FST50
,它产生一个紧凑的基于 FST 的内存数据结构,这对于文本标签器尤其有利。
Schema 配置
curl -X POST -H 'Content-type:application/json' https://127.0.0.1:8983/solr/geonames/schema -d '{
"add-field-type":{
"name":"tag",
"class":"solr.TextField",
"postingsFormat":"FST50",
"omitNorms":true,
"omitTermFreqAndPositions":true,
"indexAnalyzer":{
"tokenizer":{
"class":"solr.StandardTokenizerFactory" },
"filters":[
{"class":"solr.EnglishPossessiveFilterFactory"},
{"class":"solr.ASCIIFoldingFilterFactory"},
{"class":"solr.LowerCaseFilterFactory"},
{"class":"solr.ConcatenateGraphFilterFactory", "preservePositionIncrements":false }
]},
"queryAnalyzer":{
"tokenizer":{
"class":"solr.StandardTokenizerFactory" },
"filters":[
{"class":"solr.EnglishPossessiveFilterFactory"},
{"class":"solr.ASCIIFoldingFilterFactory"},
{"class":"solr.LowerCaseFilterFactory"}
]}
},
"add-field":{"name":"name", "type":"text_general"},
"add-field":{"name":"name_tag", "type":"tag", "stored":false },
"add-copy-field":{"source":"name", "dest":["name_tag"]}
}'
配置自定义 Solr 请求处理程序
curl -X POST -H 'Content-type:application/json' https://127.0.0.1:8983/solr/geonames/config -d '{
"add-requesthandler" : {
"name": "/tag",
"class":"solr.TaggerRequestHandler",
"defaults":{"field":"name_tag"}
}
}'
加载一些示例数据
我们将使用 CSV 格式的 Geonames.org 数据。Solr 可以非常灵活地加载各种格式的数据。这个 cities1000.zip 应该是一个大约 7MB 的文件,解压后会得到一个大约 22.2MB 的 cities1000.txt 文件,其中包含 145k 行,每一行代表世界上至少有 1000 人口的城市。
使用 bin/solr post
$ bin/solr post -c geonames -t text/csv \
--params 'optimize=true&maxSegments=1&separator=%09&encapsulator=%00&fieldnames=id,name,,alternative_names,latitude,longitude,,,countrycode,,,,,,population,elevation,,timezone,lastupdate' \
/tmp/cities1000.txt
或使用 curl
$ curl -X POST --data-binary @/path/to/cities1000.txt -H 'Content-type:application/csv' \
'https://127.0.0.1:8983/solr/geonames/update?commit=true&optimize=true&maxSegments=1&separator=%09&encapsulator=%00&fieldnames=id,name,,alternative_names,latitude,longitude,,,countrycode,,,,,,population,elevation,,timezone,lastupdate'
这可能需要大约 35 秒;这取决于情况。如果 schema 仅针对我们真正需要的内容进行调整(如果不需要文本搜索,则不需要),则速度会快得多。
在该命令中,我们使用了 optimize=true&maxSegments=1
将索引置于一种可以加快标记速度的状态。encapsulator=%00
是一种禁用默认双引号的小技巧。
标记时间!
这是一个标记一小段文本的简单示例。有关更多选项,请参阅前面的文档。
$ curl -X POST \
'https://127.0.0.1:8983/solr/geonames/tag?overlaps=NO_SUB&tagsLimit=5000&fl=id,name,countrycode&wt=json&indent=on' \
-H 'Content-Type:text/plain' -d 'Hello New York City'
响应应该是这样的(QTime 可能有所不同)
{
"responseHeader":{
"status":0,
"QTime":1},
"tagsCount":1,
"tags":[{
"startOffset":6,
"endOffset":19,
"ids":["5128581"]}],
"response":{"numFound":1,"start":0,"docs":[
{
"id":"5128581",
"name":["New York City"],
"countrycode":["US"]}]
}}
标签器性能提示
-
请遵循上述建议的配置字段设置。此外,为了获得最佳标签器性能,请设置
postingsFormat=FST50
。但是,非默认的 postings 格式没有向后兼容性保证,因此,如果您升级 Solr,则可能会在启动时发现一个令人讨厌的异常,因为它无法读取旧索引。如果要标记的输入文本很小(例如,您正在标记查询或推文),则 postings 格式的选择并不那么重要。 -
在将字典加载到一个 Lucene 段后,或者至少尽可能少地加载到段后,进行 "优化"。
-
对于批量标记大量文档,有一些策略,这些策略并非互斥:
-
对它们进行批处理。标签器不直接支持批处理,但作为一种技巧,您可以发送一堆文档,并在它们之间用一个字典中不存在的无意义的单词(如 "ZZYYXXAABBCC")连接起来。您需要跟踪这些字符偏移量,以便从结果中减去它们。
-
为了进一步减少标记延迟,请考虑使用
EmbeddedSolrServer
嵌入 Solr。请参阅EmbeddedSolrNoSerializeTest
。 -
使用多个线程 - 也许与 Solr 可用的 CPU 内核数量一样多。
-