实现断字符和词干分析器

Microsoft 为多种语言提供断字符和词干分析器。 本主题介绍如何实现和使用自定义断字符和词干分析器(适用于 Microsoft 提供的语言)和区域设置。

注意

自 2018 年 7 月起,对 Windows Server 2019 进行了安全更改,防止在没有 Microsoft 签名的情况下由SearchIndexer.exe加载 DLL。 因此,Windows Server 2019 不再支持非 Microsoft 签名的自定义断字符。

本主题按如下所示进行组织:

注册语言资源 DLL

每个语言资源 DLL 必须实现并导出以下入口点。 DLL 可以注册到任何文件夹中。

  • DllMain 是 DLL 的标准入口点。
  • DllRegisterServer 在注册表中注册 DLL,例如 regsvr32.exe %SystemRoot%\MyFolder\wordbreaker.dll
  • DllCanUnloadNow 使客户端能够通过组件对象模型调用此入口点 (COM) ,以确定是否可以卸载语言资源 DLL。
  • DllUnRegisterServer 从注册表中删除 DLL。

注册语言

注册表包含所编制语言的特定于语言的条目,这些条目控制特定于语言的索引和查询过程的各个部分。 可以在以下注册表项下找到这些注册表项。

HKEY_LOCAL_MACHINE
   SYSTEM
      CurrentControlSet
         ContentIndex
            Control
               Language
                  

实现 Word Beaker

断字符实现 IWordBreakerIWordBreaker::BreakText 方法执行所有文本处理和分析。 若要实现断字符组件,必须具有语言启发式语言。 这包括有关语法和形态的信息。 可能还需要一个字词列表来排除或包含。 从排除字词列表中生成语言区域设置的干扰词文件。 有关语言注意事项以及这些注意事项如何影响断字符实现的详细信息,请参阅 语言和 Unicode 注意事项

IWordBreaker::BreakText 的主要用途是从TEXT_SOURCE持续处理文本,直到处理完所有文本,或者直到断字符遇到错误。 在此数据处理循环中, IWordBreaker::BreakText 调用分析方法以及执行该过程的特定任务的实用工具方法。 例如,德语断字符可以处理复合词,而法语断字符可以处理 音调 符号或 clitics。 断字符执行的特定函数及其执行这些任务时使用的策略完全取决于该语言的要求。

中断文本时,断字符识别可能具有多个表示形式的单词的“备用”窗体。 生成的单词之间没有隐含语义关系。 事实上,原始单词可能不包括在替代项列表中。 备用窗体保存在索引中与原始单词相同的位置,以指示它们相同。

在索引中包含文档时,将为每个单词分配一个整数值,该值代表偏移量或单词与文档开头的距离。 查询中单词之间的相对距离与全文索引中存储的偏移量进行比较。 查询“Where is Kyle's document”与偏移量为 n 的“Where”、n+1 处的“is”、n+2 处的“Kyle”和 n+3 处的“document”匹配任何文档。 “凯尔在数据基础中提交的文件在哪里?” 表示为:

               
其中 is 凯尔·凯尔的
文档 提交 in the 数据库数据库

 

在此示例中,断字符在索引中存储“Kyle” (“Kyle”) 和“database” (“data base”) 的替代形式。 断字符在索引创建过程中生成并存储替代词,条件如下:

  • 如果替代词可能显示为查询中的单个单词
  • 如果词干分析器不太可能从替代词派生原始词

生成替代词形式会增加查询表示和匹配句子的方式的数量,如以下变体所示:

  1. 在数据库中提交的 Kyle 文档的位置
  2. 凯尔在数据库中提交的文件在哪里
  3. 在数据库中提交的 Kyle 文档在哪里
  4. 凯尔在数据源中提交的文件在哪里

WordSink 和 PhraseSink

断字符使用 IWordSinkIPhraseSink 对象收集并存储从文本中提取的所有单词和短语。 断字符将单词存储在与文档中原始单词窗体尽可能接近的窗体中。 IPhraseSink 在查询时存储短语。 短语提高了查询结果的相关性,因为较长的单词序列比较少,并且比较小的短语更区分。 当索引器在查询时在 IPhraseSink 中放置短语时,它会创建断字符的实例,将短语分解成单词。 然后,索引器通过检查短语中的单词是否在索引中彼此相邻来评估短语。 例如,如果在位置 xx+1、 x+2 和 x+3 的索引中出现“ABCD”,则如果在查询中提交“ABCD”的任何相邻子字符串,短语匹配将发生。 此策略对基于字符的断字符有效,用于在创建索引期间拆分短语和长词,并在查询期间生成短语。

分隔符

分隔符是单词之间的空格。 空格、标点符号、格式设置或语言本身的性质可能会导致中断。 索引器使用的四种不同类型的断符:词尾 (EOW) 、句子结尾 (EOS) 、段落结尾 (EOP) 和 EOC) (章节的结尾。 EOW 中断是默认中断。 每个标记后,每个中断都指示两侧单词之间的语义距离不同。 EOW 分隔的单词具有最紧密的语义链接,后跟 EOS、EOP 和 EOC。 对 IWordSink::P utBreak 的多次调用是累积的,类似于插入空单词或句子。

可伸缩性、性能和安全性

断字符响应同时调用的方式在很大程度上取决于你选择的线程模型。 索引器是单线程应用程序。 若要使断字符在单线程环境中工作,必须使用“免费”或“两者”线程模型编写断字符。 断字符不得使用“单元”线程模型向 COM 注册。

我们建议断字符避免全局状态,并将数据存储在断字符实例中。 应在断字符实现中存储的唯一内容是参数 fQueryulMaxTokenSize。 断字符不应比英语断字符建立的基准慢两倍以上。 断字符性能还应提高硬件功能。

索引器的断字符在本地系统安全上下文中运行。 它们应写入以管理缓冲区并正确堆叠。 所有字符串副本都必须进行显式检查,以防止缓冲区溢出。 应始终验证缓冲区的分配大小,并针对缓冲区的大小测试数据的大小。 断字符不能假定传递给 IWordBreaker::BreakText 方法的文本格式良好。 有关断字符疑难解答的详细信息,请参阅 语言资源和最佳做法疑难解答

实现词干分析器

词干分析器实现 IStemmer 接口。 IStemmer::GenerateWordForms 方法为特定输入词生成一个转折字窗体列表。 若要实现词干分析器组件,必须具有语言启发式语言。 这包括有关形态的信息。 可能还需要一个字词列表来排除或包含。 有关语言注意事项以及这些注意事项如何影响词干分析器实现的详细信息,请参阅 语言和 Unicode 注意事项

我们建议词干分析器不应生成单词的根性或拥有性。 例如,“David”不是作为“David's”的替代形式生成的。断字符在分析“David”时生成“David”和“David's”。

词干分析器使用 IWordFormSink 对象收集备用词的列表。 IWordFormSink::P utWord 从词干分析器生成最终单词。 在所有情况下,此最终单词与 IStemmer::GenerateWordForms 中的输入词相同。 例如,鉴于词“游泳”,词干分析器通过调用 IWordFormSink::P utAltWord 生成以下词形式:“游泳”、“游泳”、“游泳”、“swam”和“swum”。 词干分析器通过 IWordFormSink::P utWord 生成“游泳”。

可伸缩性、性能和安全性

词干分析器(如断字符)必须使用“免费”线程模型,并在其线程模型设置为“free”或“两者”的情况下向 COM 注册。Windows搜索同时调用不同线程的词干分析器实例。 因此,词干分析器应具有最少的实例数据。

词干分析器准确性对查询相关性产生重大影响。 如果词干分析器错误地词干文本,则查询可能会返回不可预知和不准确的结果。 词干分析器每秒必须处理数百个查询,而不会对查询性能产生负面影响。 随着硬件功能的提高,词干分析器性能应提高。 有关词干分析器故障排除的信息,请参阅 语言资源和最佳做法疑难解答

用于Windows搜索的词干分析器在本地安全上下文中运行。 它们应写入以管理缓冲区并正确堆叠。 所有字符串副本都必须进行显式检查,以防止缓冲区溢出。 应始终验证缓冲区的分配大小,并针对缓冲区的大小测试数据的大小。

扩展语言资源

了解语言资源组件

语言和 Unicode 注意事项

语言资源和最佳做法疑难解答