ElasticSearch search_as_you_type字段分词机制及验证方法问询
你的配置下的实际分词结果(和预期不符的原因)
你使用的partial_words分析器是字符级ngram分词器,而非词级的shingle过滤器,这导致search_as_you_type字段的分词结果和你预想的词组合完全不同:
1. my_text.shingles
主字段直接走partial_words分析器逻辑:先将每个单词切成3-10个字符的连续ngram片段,再转成小写。以文本"Martin Luther was a german priest"为例,分词结果为大量字符片段(示例):
[mar, art, rti, tin, mart, arti, rtin, marti, artin, martin, lut, uth, the, her, luth, uthe, ther, luthe, uther, luther, was, ger, erm, rma, man, germ, erma, rman, german, pri, rie, ies, est, prie, riest, priest]
2. my_text.shingles._2gram
search_as_you_type的_2gram子字段会在主分析器基础上自动添加词级shingle过滤,但这里的"词"是前面生成的字符ngram,所以结果是字符ngram的两两拼接组合:
[mar art, art rti, rti tin, lut uth, uth the, was was, ger erm, ...]
3. my_text.shingles._3gram
同理,_3gram子字段会生成字符ngram的三三连续拼接组合:
[mar art rti, art rti tin, lut uth the, ...]
验证分词结果的方法
用Elasticsearch的_analyze API可直接查看分词逻辑,两种常用方式:
方式1:指定字段测试
直接针对目标字段测试,替换你的索引名为实际索引名称:
POST /你的索引名/_analyze { "field": "my_text.shingles", "text": "Martin Luther was a german priest" }
将field参数替换为my_text.shingles._2gram或my_text.shingles._3gram,即可查看对应子字段的分词结果。
方式2:单独测试分析器
若只想验证partial_words分析器的效果,可发送以下请求:
POST /_analyze { "analyzer": "partial_words", "text": "Martin Luther was a german priest" }
如何得到你预期的词级shingle结果
如果想生成Martin Luther这类词级组合,需要调整分析器配置:使用标准分词器拆分单词,再添加shingle过滤器,而非使用ngram tokenizer。参考配置如下:
{ "settings": { "analysis": { "filter": { "word_shingle": { "type": "shingle", "min_shingle_size": 2, "max_shingle_size": 3 } }, "analyzer": { "phrase_shingles": { "type": "custom", "tokenizer": "standard", "filter": ["lowercase", "word_shingle"] } } } }, "mappings": { "properties": { "my_text": { "type": "text", "fields": { "shingles": { "type": "search_as_you_type", "analyzer": "phrase_shingles" } } } } } }
此时my_text.shingles._2gram会生成你预期的[martin luther, luther was, was a, a german, german priest],my_text.shingles._3gram会生成[martin luther was, luther was a, was a german, a german priest]。
内容的提问来源于stack exchange,提问作者toch

