实现Word断路器和词干分析器
Microsoft 为多种语言提供断字符和词干分析器。 本主题介绍如何实现和使用 Microsoft 提供的语言和区域设置之外的自定义断字符和词干分析器。
注意
自定义断字符暂时不受支持。 2018 年 7 月,对 Windows Server 2019 进行了更改,阻止 SearchIndexer.exe 加载没有 Microsoft 签名的 DLL。 此限制已于 2021 年 1 月解除。
本主题的组织方式如下:
注册语言资源 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
Word中断程序实现 IWordBreaker。 IWordBreaker::BreakText 方法执行所有文本处理和分析。 若要实现断字符组件,必须为语言提供语言启发式。 这包括有关语法和形态的信息。 可能还需要一个要排除或包含的字词列表。 从排除的字词列表中生成语言区域设置的干扰词文件。 有关语言注意事项以及这些注意事项如何影响断字符实现的详细信息,请参阅 语言和 Unicode 注意事项。
IWordBreaker::BreakText main用途是从TEXT_SOURCE连续处理文本,直到处理所有文本,或直到断字符遇到错误。 在此数据处理循环中, IWordBreaker::BreakText 调用为该过程执行特定任务的分析和实用工具方法。 例如,德语断字符可以处理复合词,而法语断字符可以处理音调符号或 clitic。 断字符执行的特定函数及其在执行这些任务时使用的策略完全取决于该语言的要求。
中断文本时,断字符会识别可能具有多个表示形式的单词的“备用”形式。 生成的字词之间没有隐含语义关系。 事实上,原始单词可能不会包含在替代项列表中。 备用窗体保存在索引中与原始单词相同的位置,以指示它们相同。
当文档包含在索引中时,将为每个单词分配一个整数值,该值表示该单词与文档开头的偏移量或距离。 查询中单词之间的相对距离与全文索引中存储的偏移量进行比较。 查询“Where is Kyle 的文档”匹配偏移 n 处的“Where”、n+1 的“is”、n+2 的“Kyle's”和 n+3 的“document”的任何文档。 “Kyle 的文档在数据库中存档在哪里?” 表示为:
其中 | is | 凯尔凯尔的 |
文档 | 提交 | in | the | 数据库数据库数据库 |
在此示例中,断字符将“Kyle” (“Kyle's”) 和“database” (“data base”) 存储在索引中。 在以下条件下,断字符在索引创建过程中生成并存储备用字词:
- 如果替代词可能显示为查询中的单个单词
- 如果词干分析器不太可能从替代词派生原始单词
生成替代词窗体会增加查询表示和匹配句子的次数,如以下变体所示:
- 在数据库中存档的 Kyle 文档的位置
- 凯尔在数据库中归档的文档在哪里
- 在数据库中存档的 Kyle 文档的位置
- 凯尔的文档在数据库中存档的位置
WordSink 和 PhraseSink
Word断层使用 IWordSink 和 IPhraseSink 对象来收集和存储它们从文本中提取的所有单词和短语。 断字符将单词存储在尽可能接近文档中原始单词窗体的窗体中。 IPhraseSink 在查询时存储短语。 短语提高了查询结果的相关性,因为较长的字词序列比较小的短语更罕见,并且提供更大的区别。 当索引器在查询时将短语置于 IPhraseSink 中时,它会创建断字符的实例,以将短语拆分为单词。 然后,索引器通过检查短语中的单词是否位于索引中相邻来计算短语。 例如,如果“ABCD”出现在索引位置 x、 x+1、 x+2 和 x+3 位置,则如果在查询中提交“ABCD”的任何相邻子字符串,将发生短语匹配。 此策略适用于在创建索引期间拆分短语和长字并在查询期间生成短语的基于字符的断字符。
分隔符
分隔符是单词之间的空格。 空格、标点符号、格式设置或仅语言本身的性质可能会导致中断。 索引器使用四种不同类型的分隔符:EOW) (单词结尾、EOS) (句尾、段落 (EOP) 结尾和 EOC) 章节 (尾。 EOW 中断是默认的中断。 在每个标记之后,每个断点表示两侧单词之间的语义距离不同。 由 EOW 分隔的单词具有最紧密的语义链接,后跟 EOS、EOP 和 EOC。 多次调用 IWordSink::P utBreak 是累积的,类似于插入空单词或句子。
可伸缩性、性能和安全性
断字符响应同时调用的方式在很大程度上取决于你选择的线程模型。 索引器是单线程应用程序。 若要在单线程环境中运行断字符,必须使用“免费”或“两者”线程模型编写断字符。 Word断路器不得使用“单元”线程模型向 COM 注册。
建议断字符避免全局状态,并将数据存储在断字符实例中。 应存储在断字符实现中的唯一内容是参数 fQuery 和 ulMaxTokenSize。 Word断字符的速度不应比英语断字符建立的基准慢两倍。 Word断路器性能还应随着硬件功能的提高而提高。
Word索引器的中断程序在本地系统安全上下文中运行。 应编写它们以管理缓冲区和正确堆叠。 所有字符串副本都必须具有显式检查,以防止缓冲区溢出。 应始终验证已分配的缓冲区大小,并对照缓冲区的大小测试数据的大小。 Word断字符不能假定传递到 IWordBreaker::BreakText 方法的文本格式良好。 有关对断字符进行故障排除的详细信息,请参阅 语言资源和最佳做法疑难解答。
实现词干分析器
词干分析器实现 IStemmer 接口。 IStemmer::GenerateWordForms 方法为特定输入词生成转换词窗体的列表。 若要实现词干分析器组件,必须具有语言的启发式语言。 这包括有关形态的信息。 可能还需要一个要排除或包含的字词列表。 有关语言注意事项以及这些注意事项如何影响词干分析器实现的详细信息,请参阅 语言和 Unicode 注意事项。
我们建议词干分析器不应生成单词的天生或占有性大小写。 例如,“David”不是作为“David's”的替代形式生成的。断字符在分析“David's”时生成“David”和“David's”。
词干分析器使用 IWordFormSink 对象来收集可选字词的列表。 IWordFormSink::P utWord 从词干分析器生成最终单词。 在所有情况下,此最后一个单词都与 IStemmer::GenerateWordForms 中的输入词相同。 例如,给定单词“游泳”,词干分析器通过调用 IWordFormSink::P utAltWord 生成以下单词形式:“游泳”、“游泳者”、“游泳”、“swam”和“swum”。 词干分析器通过 IWordFormSink::P utWord 生成“游泳”。
可伸缩性、性能和安全性
词干分析器(如断字符)必须使用“免费”线程模型,并在 COM 中注册其线程模型设置为“free”或“两者”。Windows 搜索同时从不同的线程调用词干分析器的不同实例。 因此,词干分析器应具有最少的实例数据。
词干分析器准确性对查询相关性有重大影响。 如果词干分析器错误地词干文本,则查询可能会返回不可预测的不准确结果。 词干分析器必须每秒处理数百个查询,而不会对查询性能产生负面影响。 随着硬件功能的提高,词干分析器性能应得到提高。 有关排查词干分析器问题的信息,请参阅 语言资源和最佳做法疑难解答。
Windows 搜索的词干分析器在本地安全上下文中运行。 应编写它们以管理缓冲区和正确堆叠。 所有字符串副本都必须具有显式检查,以防止缓冲区溢出。 应始终验证已分配的缓冲区大小,并对照缓冲区的大小测试数据的大小。
相关主题