全字段配自定义分析器时索引级tokenizer等组件的生效时机
问题描述
如果索引定义中的每个字段都已为索引构建与搜索查询流程配置了自定义分析器,那么索引级别的tokenizers、tokenFilters、CharFilters会在什么场景下被调用?
示例配置如下:
Index indexDefiniton = new Index() { Name = myIndexName, Fields = FieldBuilder.BuildForType<AzureIndexDocument>(), Analyzers = new[] { new CustomAnalyzer() { Name = indexConstants.DefaultIndexAnalyzerName, CharFilters = new[] { CharFilterName.Create(indexConstants.SlashFilterName), CharFilterName.Create(indexConstants.DashFilterName) }, Tokenizer = TokenizerName.Whitespace, TokenFilters = new[] { TokenFilterName.Lowercase}, }, new CustomAnalyzer() { Name = indexConstants.PrefixAnalyzerName, Tokenizer = TokenizerName.Whitespace, TokenFilters = new[] { TokenFilterName.Lowercase, TokenFilterName.Stopwords, }, }, new CustomAnalyzer() { Name = indexConstants.SearchTermAnalyzerName, Tokenizer = TokenizerName.Whitespace, TokenFilters = new[] { TokenFilterName.Lowercase } }, new CustomAnalyzer() { Name = indexConstants.KeywordIndexAnalyzer, Tokenizer = TokenizerName.Keyword, TokenFilters = new[] { TokenFilterName.Lowercase , TokenFilterName.Trim } } }, TokenFilters = new List<TokenFilter> { new EdgeNGramTokenFilterV2 { Name = indexConstants.PrefixCreatingTokenFilterName, MinGram = 1, MaxGram = 50 }, new WordDelimiterTokenFilter { Name = indexConstants.CatenateNumberFilterTokenFilterName , CatenateNumbers = true, CatenateWords = true, CatenateAll = true , PreserveOriginal = true } }, CharFilters = new List<CharFilter> { new PatternReplaceCharFilter(indexConstants.SlashFilterName, s_Slash, s_Space), new PatternReplaceCharFilter(indexConstants.DashFilterName, s_Dash, s_Space), new PatternReplaceCharFilter(indexConstants.UnderScoreFilterName, s_UnderScore, s_Space), new PatternReplaceCharFilter(indexConstants.RoundBracketOpeningFilterName, s_RoundBracketOpening, s_Space), new PatternReplaceCharFilter(indexConstants.RoundBracketClosingFilterName, s_RoundBracketClosing, s_Space) }, };
假设该索引定义中声明的所有字段,索引阶段均使用前文定义的keyword/prefix/default分析器,搜索阶段均使用指定的searchAnalyzer,请问索引层级定义的TokenFilter(包括EdgeNGramTokenFilterV2、WordDelimiterTokenFilter)、CharFilters会在什么场景下被触发使用?
答案
Azure AI Search 中索引层级定义的Tokenizer、TokenFilter、CharFilter属于全局可复用的自定义组件资源,不会自动挂载到任何分析链路生效,只有被自定义分析器显式引用时,才会在对应分析器的运行场景中被调用,不存在字段配置了自定义分析器时索引级组件会自动追加执行的逻辑。
结合给出的配置和前提,各组件触发场景如下:
- 已被自定义分析器引用的组件:
SlashFilterName、DashFilterName两个字符过滤器
这两个过滤器被配置在DefaultIndexAnalyzerName自定义分析器的CharFilters列表中,会在所有使用该默认分析器做索引分词的字段写入数据时触发,执行斜杠、短横替换为空格的预处理逻辑。 - 未被任何自定义分析器引用的组件:包括
EdgeNGramTokenFilterV2、WordDelimiterTokenFilter两个词元过滤器,以及UnderScoreFilterName、RoundBracketOpeningFilterName、RoundBracketClosingFilterName三个字符过滤器
这些组件在当前配置下属于冗余定义,不会在任何索引写入、搜索查询场景下被触发。
如果后续需要启用这些未使用的组件,只需要把对应组件名添加到目标自定义分析器的CharFilters/TokenFilters配置列表中即可:组件会按照你在分析器配置里声明的顺序执行,触发场景和对应分析器的生效阶段一致——如果分析器被配置为字段的索引分析器(indexAnalyzer),则在数据写入构建倒排索引时触发;如果被配置为搜索分析器(searchAnalyzer),则在用户输入查询词执行搜索时触发。
举个例子:如果你把PrefixCreatingTokenFilterName(即EdgeNGram词元过滤器)添加到PrefixAnalyzerName的TokenFilters列表末尾,那么后续所有使用PrefixAnalyzer做索引分词的字段,写入时就会在执行完小写转换、停用词过滤后,额外执行EdgeNGram逻辑生成指定长度的前缀词元,用于前缀匹配搜索。
内容的提问来源于stack exchange,提问作者G Sai Kanth

