ElasticSearch分词原理
术语
- term:分词
- analyzer: 分析器
- CharFilters:字符过滤器
- Tokenizer:分词器
- TokenFilters:分词过滤器
Analysis 简介
当一个文档被索引时,每个field都可能会创建一个倒排索引(如果mapping的时候没有设置不索引该field)。倒排索引的过程就是将文档通过analyzer分成一个一个的term,每一个term都指向包含这个term的文档集合。当查询query时,elasticsearch会根据搜索类型决定是否对query进行analyze,然后和倒排索引中的term进行相关性查询,匹配相应的文档
CharFilters:使用字符过滤器转变字符
Tokenizer:将文本切分单个或者多个分词
TokenFilters:使用分词过滤器转变每个分词
analyzer = CharFilters(0个或多个) + Tokenizer(恰好一个) + TokenFilters(0个或多个)
执行顺序:CharFilters->Tokenizer->TokenFilters
CharFilters:HTML Strip
, mapping
,pattern
三种,mapping字符过滤器和分词过滤器中同义词过滤容易混淆
Tokenizer:分类三个大类,word oriented
,partial word
,struct text
, 其中word oriented
中的standard分词器用的最多,partial word
中的nGram分析器用的较多
index analyzer VS search analyzer
如果mapping中只设置了一个analyzer,那么这个analyzer会同时用于索引文档和搜索query。当然索引文档和对query进行analysis也可以使用不同的analyzer
一个特殊的情况是有的query是需要被analyzed,有的并不需要。例如match query
会先用search analyzer进行分析,然后去相应field的倒排索引进行匹配。而term query
并不会对query内容进行分析,而是直接和相应field的倒排索引去匹配
Analyze API
Analyze API是一个有效的方式查看分析后的结果:
POST _analyze
{
"analyzer" : "standard",
"text" : "hello, world"
}
输出的结果如下所示,即[hello, world]
:
自定义分析器
{
"index": {
"number_of_shards": "1",
"provided_name": "stock_basic_info",
"creation_date": "1562167043908",
"analysis": {
"analyzer": {
"ngram_analyzer": {
"type": "custom",
"tokenizer": "ngram_tokenizer"
}
},
"tokenizer": {
"ngram_tokenizer": {
"type": "nGram",
"min_gram": "1",
"max_gram": "20"
}
}
},
"number_of_replicas": "0",
"uuid": "VHpU8lzRTliQ7SeU0kRevQ",
"version": {
"created": "5060899"
}
}
}
使用自定义分析器
curl -X POST \
'http://192.168.1.100:9200/stock_basic_info/_analyze?=' \
-H 'Content-Type: application/json' \
-d '{
"analyzer": "ngram_analyzer",
"text": "000001.SZ"
}'
全局配置vs动态配置
配置分析器可以在配置文件中全局配置,也可以在创建时指定分析器,全局配置使用起来简单,灵活性差,需要重启才能生效,动态配置使用复杂,灵活性强,实时生效