Elasticsearch标准分词器分隔符及自定义需求技术问询
关于Elasticsearch Standard Analyzer的定制需求疑问
问题背景
- Elasticsearch的standard analyzer依赖standard tokenizer生成词元,官方说明采用语法分词,但standard tokenizer的具体分隔规则并不明确。
- 我的实际需求:
- 索引中部分字段使用默认的standard analyzer;
- 需要让这些字段中的
#字符可被搜索(即分词时保留#与后续内容绑定),同时将.作为额外的分词分隔符(把john.s拆成john和s)。想问能不能通过原生standard analyzer实现这个需求?
测试过程与结果
我测试了字符串「hey john.s #100 is a test name」的分词效果,执行请求:
POST _analyze { "text": "hey john.s #100 is a test name", "analyzer": "standard" }
得到的词元结果:
{ "tokens": [ { "token": "hey", "start_offset": 0, "end_offset": 3, "type": "<ALPHANUM>", "position": 0 }, { "token": "john.s", "start_offset": 4, "end_offset": 10, "type": "<ALPHANUM>", "position": 1 }, { "token": "100", "start_offset": 12, "end_offset": 15, "type": "<NUM>", "position": 2 }, { "token": "is", "start_offset": 16, "end_offset": 18, "type": "<ALPHANUM>", "position": 3 }, { "token": "a", "start_offset": 19, "end_offset": 20, "type": "<ALPHANUM>", "position": 4 }, { "token": "test", "start_offset": 21, "end_offset": 25, "type": "<ALPHANUM>", "position": 5 }, { "token": "name", "start_offset": 26, "end_offset": 30, "type": "<ALPHANUM>", "position": 6 } ] }
从结果来看,#被直接丢弃,.没有作为分隔符,因此产生疑问:standard tokenizer是不是只把空格当成分隔符?
解答
1. standard tokenizer的分隔规则
standard tokenizer并非只以空格为分隔符,它遵循Unicode文本分割算法,会将空格、大部分标点符号作为分隔符,但像.、'这类连接型标点会被保留在词元中;而#属于会被识别为分隔符并直接丢弃的符号,所以#100会被拆成100。
2. 原生standard analyzer无法满足需求
原生standard analyzer的组件(standard tokenizer + 小写转换等固定filter)是不可修改的,无法实现:
- 保留
#字符在词元中; - 将
.作为分词分隔符拆分词元。
3. 自定义analyzer实现需求
要满足你的需求,需要创建一个自定义analyzer,示例配置如下:
PUT /my_index { "settings": { "analysis": { "analyzer": { "custom_standard_like": { "tokenizer": "whitespace", "filter": [ "custom_word_delimiter", "lowercase" ] } }, "filter": { "custom_word_delimiter": { "type": "word_delimiter", "split_on_symbol": true, // 开启按符号分割,包含`.` "generate_word_parts": true, "generate_number_parts": true, "preserve_original": false } } } } }
测试这个自定义analyzer:
POST my_index/_analyze { "text": "hey john.s #100 is a test name", "analyzer": "custom_standard_like" }
会得到符合需求的词元:hey, john, s, #100, is, a, test, name——既拆分了.分隔的内容,又保留了#与100的绑定,确保#100可以被精准搜索。
内容的提问来源于stack exchange,提问作者randomDev
相关产品推荐
相关产品推荐

