官网文档
https://www.elastic.co/guide/en/elasticsearch/reference/6.7/analysis.html
概要
文本分析是一个处理过程,他将一段文本(例如一封email或一句话)转化为一个个token或term(可以理解为词语或单词),然后将他们添加到倒排索引中用来查询。文本分析是由分析器执行的,可以是内置的也可以是每个索引自定义的。
索引时的分析
例如,在索引的时候,内置的 english 分析器,会将下面的句子进行转换:
“The QUICK brown foxes jumped over the lazy dog!”
转换为不同的token。它会将各token转化为小写,删除常用的停用词(“the”),将term简化为词根 (foxes → fox, jumped → jump, lazy → lazi)。最后,下面的term会被添加到倒排索引中:
[ quick, brown, fox, jump, over, lazi, dog ]
指定索引时候的分析器
在mapping中的任何 text 类型的字段可以指定它自己的分析器( analyzer ):
curl -X PUT "localhost:9200/my_index?pretty" -H 'Content-Type: application/json' -d'{"mappings": {"_doc": {"properties": {"title": {"type": "text","analyzer": "standard"}}}}}'
在索引时,如果没有指定 analyzer ,它会寻找index settings中名称为default的analyzer。否则,默认使用standard analyzer。
查询时的分析
在执行full text queries (如match query)时,相同的分析过程会应用在查询字符串上,将查询字符串的文本转换为与存储在倒排索引中相同形式的term。
例如,用户可能搜索:
“a quick fox”
它会被相同的english analyzer 分析为下面的term:
[ quick, fox ]
尽管查询信息中使用的确切单词在原始文本中没有出现(quick vs QUICK, fox vs foxes),但是因为原始文本和查询信息使用相同的analyzer,查询信息的term和倒排索引中原始文本的term完全匹配,这意味着这个查询会匹配我们的样例document。
指定查询时的分析器
通常在索引和查询时使用相同的analyzer,full text queries(如match query)会使用mapping查找每个字段使用的analyzer。
搜索某个特定字段而使用的analyzer(优先级)取决于:
- 在query中指定的 analyzer
- mapping参数 search_analyzer
- mapping参数 analyzer
- index settings参数 default_search
- index settings参数 default
- standard analyzer
剖析分析器
无论是内置的还是自定义的analyzer,只是一个包含了3个更低级的构建块:character filters, tokenizers, and token filters的包。
内置的analyzer将这些构建块预先打包到适合不同语言和文本类型的analyzer中。Elasticsearch还公开了各个构件块,以便他们可以组合起来定义新的自定义analyzer。
Character filters
character filter接收原始文本作为一个字符流,可以通过增加、删除、修改字符来转换改流。例如,一个character filter可以将印度-阿拉伯数字(٠١٢٣٤٥٦٧٨٩)转化为阿拉伯-拉丁数字(0123456789),或者从流中过滤像这样的HTML元素
一个analyzer可以拥有0或多个character filter,他们按顺序应用。
Tokenizer
tokenizer接收一个字符流,将其分解为单个的token(通常是单个的单词),并输出一个token流。例如,whitespace tokenizer当遇到空格时,会将文本分解为token。它会将文件”Quick brown fox!”转换为term[Quick, brown, fox!]。
tokenizer还负责记录每个term的顺序和位置,以及改term所表示的原单词的开始和结束字符的偏移量。
Token filters
token filter接收token流,并且可以对其中的token进行增加、删除、修改。例如,lowercase token filter将所有的token转为小写,stop token filter可以从token流中删除像the的通用单词(停用词),synonym token filter将同义词引入token流。
token filter不允许修改任何token的位置和字符偏移量。
一个analyzer可有拥有0个或多个token filter,他们按顺序应用。
测试分析器
analyze API是一个无价的工具,可以查看analyzer产生的term。内置的analyzer(或者使用内置的tokenizer, token filters, character filters组合的)可以在请求正文中指定:
curl -X POST "localhost:9200/_analyze?pretty" -H 'Content-Type: application/json' -d'{"analyzer": "whitespace","text": "The quick brown fox."}'curl -X POST "localhost:9200/_analyze?pretty" -H 'Content-Type: application/json' -d'{"tokenizer": "standard","filter": [ "lowercase", "asciifolding" ],"text": "Is this déja vu?"}'
位置和字符偏移量 ** 从analyze API的输出看,analyzer不仅将单词转为term,还记录了term的顺序和相对位置(用于phrase queries or word proximity queries),每个term在原文中的开始和结束字符的偏移量(用于高亮查询)。
另外,在明确的index上执行analyze API时,custom analyzer可以被引用。
curl -X PUT "localhost:9200/my_index?pretty" -H 'Content-Type: application/json' -d'{"settings": {"analysis": {"analyzer": {"std_folded": {"type": "custom","tokenizer": "standard","filter": ["lowercase","asciifolding"]}}}},"mappings": {"_doc": {"properties": {"my_text": {"type": "text","analyzer": "std_folded"}}}}}'curl -X GET "localhost:9200/my_index/_analyze?pretty" -H 'Content-Type: application/json' -d'{"analyzer": "std_folded","text": "Is this déjà vu?"}'curl -X GET "localhost:9200/my_index/_analyze?pretty" -H 'Content-Type: application/json' -d'{"field": "my_text","text": "Is this déjà vu?"}'
第6行 定义一个名为std_folded的custom analyzer
第22行 字段custom analyzer 使用了std_folded analyzer
第29、35行 引用这个analyzer(自定义的std_folded),analyze API必须指定索引名
第31行 通过名称引用analyzer
第37行 通过字段my_text引用analyzer
Analyzers
Elasticsearch提供了广泛的内置analyzer,可以无需更多设置再任意index中使用。
- Standard Analyzer
standard analyzer按照Unicode文本分割算法,在单词边界上将文本分为term。他删除了大部分标点,小写term,且支持删除stop words。
- Simple Analyzer
当遇到一个不是字母的字符时,simple analyzer将文本分为term。所有的term转为小写。
- Whitespace Analyzer
当遇到空白字符时,whitespace analyzer将文本分为term。term不会转为小写。
- Stop Analyzer
stop analyzer与simple analyzer相似,但是支持删除stop words。
- Keyword Analyzer
keyword analyzer是一个“noop” analyzer,接收给定的任意文本,然后输出一个与文本完全相同的term。
- Pattern Analyzer
pattern analyzer使用正则表达式将文本分割为term。它支持小写和停用词。
- Language Analyzers
Elasticsearch提供了许多特定语言的analyzer,如英语好法语。
- Fingerprint Analyzer
fingerprint analyzer是一个专门的analyzer,它可以创建指纹用于重复检查。
- Custom Analyzer
如果没有发现你需要的合适的analyzer,你可以创建一个custom analyzer,它结合了适当的character filters, tokenizer, and token filters。
配置内置analyzer
内置analyzer可以不经过任何配置直接使用。然而,有些analyzer支持配置选项来改变行为。比如,standard analyzer可以通过配置支持一个stop words列表:
curl -X PUT "localhost:9200/my_index?pretty" -H 'Content-Type: application/json' -d'{"settings": {"analysis": {"analyzer": {"std_english": {"type": "standard","stopwords": "_english_"}}}},"mappings": {"_doc": {"properties": {"my_text": {"type": "text","analyzer": "standard","fields": {"english": {"type": "text","analyzer": "std_english"}}}}}}}'curl -X POST "localhost:9200/my_index/_analyze?pretty" -H 'Content-Type: application/json' -d'{"field": "my_text","text": "The old brown cow"}'curl -X POST "localhost:9200/my_index/_analyze?pretty" -H 'Content-Type: application/json' -d'{"field": "my_text.english","text": "The old brown cow"}'
第7行 我们基于standard analyzer定义了std_english analyzer,但是将其配置为删除预定义的英语停用词列表。
第18、33行 字段my_text直接使用standard analyzer,没有任何配置。没有stop words会从该字段删除。产生的term:[ the, old, brown, cow ]
第22、39行 字段my_text.english使用std_english analyzer,因此英语stop words会被删除。产生的term:[ old, brown, cow ]
Standard Analyzer
standard analyzer是默认的analyzer,没有指定则使用它。提供了基于标记的语法(基于Unicode文本分割算法,如Unicode标准附件#29中指定的),并且适用于大多数语言。
输出样例
curl -X POST "localhost:9200/_analyze?pretty" -H 'Content-Type: application/json' -d'{"analyzer": "standard","text": "The 2 QUICK Brown-Foxes jumped over the lazy dog\u0027s bone."}'
上面的句子会产生下面的term:
[ the, 2, quick, brown, foxes, jumped, over, the, lazy, dog’s, bone ]
配置
standard analyzer接受下面的参数:
- max_token_length token的最大长度。如果token超过了这个长度,他会以max_token_length间隔分割该token。默认255。
- stopwords 一个如english预定义的stop words列表或者是一个包含stop words列表的数组。默认none。
- stopwords_path 一个包含stop words的文件的路径。
配置样例
在本例中,我们配置standard analyzer的max_token_length参数为5(出于演示的目的),且使用预定义的英语stop words列表。 ```shell curl -X PUT “localhost:9200/my_index?pretty” -H ‘Content-Type: application/json’ -d’ { “settings”: { “analysis”: {
} } } ‘ curl -X POST “localhost:9200/my_index/_analyze?pretty” -H ‘Content-Type: application/json’ -d’ { “analyzer”: “my_english_analyzer”, “text”: “The 2 QUICK Brown-Foxes jumped over the lazy dog\u0027s bone.” } ‘"analyzer": {"my_english_analyzer": {"type": "standard","max_token_length": 5,"stopwords": "_english_"}}
上面的样例产生了下面的term:> [ 2, quick, brown, foxes, jumpe, d, over, lazy, dog's, bone ]<a name="NXU36"></a>### 定义standard analyzer包含:- Tokenizer- Standard Tokenizer- Token Filters- Standard Token Filter- Lower Case Token Filter- Stop Token Filter (disabled by default)如果你需要在配置参数之外自定义standard analyzer,你需要把它当做一个custom analyzer进行重建并且修改它,通常通过增加token filters。这里我们会重建内置的standard analyzer,你可以使用它作为起点:```shellcurl -X PUT "localhost:9200/standard_example?pretty" -H 'Content-Type: application/json' -d'{"settings": {"analysis": {"analyzer": {"rebuilt_standard": {"tokenizer": "standard","filter": ["lowercase"]}}}}}'
第9行 你可以在lowercase后面添加任意token filter
不再一一枚举内置 analyzer
Constom Analyzer
当内置的analyzer不能满足你的需求时,你可以使用合适的组合创建一个custom analyzer:
- 0个或多个character filters
- 1个tokenizer
-
配置
constom analyzer接受下面的参数:
tokenizer 内置或自定义的tokenizer(必填)
- char_filter 内置或自定义的character filter列表(可选)
- filete 内置或自定义的token filter列表(可选)
position_increment_gap 当索引文本数组时,Elasticsearch会在一个值的最后一个term和下一个值的第一个term之间插入一个假的间隙,以确保phrase query不会匹配不同数组元素的两个term。默认值100。
配置样例
这里有个样例,包含了下面的组合:
Character Filter
- HTML Strip Character Filter
- Tokenizer
- Standard Tokenizer
- Token Filters
- Lowercase Token Filter
- ASCII-Folding Token Filter
```shell
curl -X PUT “localhost:9200/my_index?pretty” -H ‘Content-Type: application/json’ -d’
{
“settings”: {
“analysis”: {
“analyzer”: {
“my_custom_analyzer”: {
} } } } } ‘ curl -X POST “localhost:9200/my_index/_analyze?pretty” -H ‘Content-Type: application/json’ -d’ { “analyzer”: “my_custom_analyzer”, “text”: “Is this déjà vu?” } ‘"type": "custom","tokenizer": "standard","char_filter": ["html_strip"],"filter": ["lowercase","asciifolding"]
```
第7行 设置type为custom是为了告诉Elasticsearch我们定义了一个custom analyzer。对比配置内置analyzer
type需要设置为内置analyzer,比如standard或者simple。
Token Filters
token filter从一个tokenizer接收一个token流,并且可以修改token(如小写),删除token(如删除停用词),或者增加token(如同义词)。
Elasticsearch有很多内置的token filter,可以用够构建custom analyzer。
Lowercase Token Filter
一个type为lowercase的token filter,可以将token文本规范化为小写。
Character Filters
在字符流传递给tokenizer之前,character filter对其进行预处理。
不一一枚举
