官网文档
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,你可以使用它作为起点:
```shell
curl -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对其进行预处理。
不一一枚举