analyzer的使用规则
查询只能查找倒排索引表中真实存在的项, 所以保证文档在索引时与查询字符串在搜索时应用相同的分析过程非常重要,这样查询的项才能够匹配倒排索引中的项。
尽管是在说 文档 ,不过分析器可以由每个字段决定。 每个字段都可以有不同的分析器,既可以通过配置为字段指定分析器,也可以使用更高层的类型(type)、索引(index)或节点(node)的默认配置。在索引时,一个字段值是根据配置或默认分析器分析的。
例如为 my_index
新增一个字段:
PUT /my_index/_mapping/my_type
{
"my_type": {
"properties": {
"english_title": {
"type": "string",
"analyzer": "english"
}
}
}
}
现在我们就可以通过使用 analyze
API 来分析单词 Foxes
,进而比较 english_title
字段和 title
字段在索引时的分析结果:
GET /my_index/_analyze
{
"field": "my_type.title",
"text": "Foxes"
}
GET /my_index/_analyze
{
"field": "my_type.english_title",
"text": "Foxes"
}
- 字段
title
,使用默认的standard
标准分析器,返回词项foxes
。- 字段
english_title
,使用english
英语分析器,返回词项fox
。
这意味着,如果使用底层 term
查询精确项 fox
时, english_title
字段会匹配但 title
字段不会。
如同 match
查询这样的高层查询知道字段映射的关系,能为每个被查询的字段应用正确的分析器。 可以使用 validate-query
API 查看这个行为:
GET /my_index/my_type/_validate/query?explain
{
"query": {
"bool": {
"should": [
{ "match": { "title": "Foxes"}},
{ "match": { "english_title": "Foxes"}}
]
}
}
}
返回语句的 explanation
结果:
(title:foxes english_title:fox)
match
查询为每个字段使用合适的分析器,以保证它在寻找每个项时都为该字段使用正确的格式。
默认分析器
虽然我们可以在字段层级指定分析器, 但是如果该层级没有指定任何的分析器,那么我们如何能确定这个字段使用的是哪个分析器呢?
分析器可以从三个层面进行定义:按字段(per-field)、按索引(per-index)或全局缺省(global default)。Elasticsearch 会按照以下顺序依次处理,直到它找到能够使用的分析器。索引时的顺序如下:
- 字段映射里定义的
analyzer
,否则 - 索引设置中名为
default
的分析器,默认为 standard
标准分析器
在搜索时,顺序有些许不同:
- 查询自己定义的
analyzer
,否则 - 字段映射里定义的
analyzer
,否则 - 索引设置中名为
default
的分析器,默认为 standard
标准分析器
有时,在索引时和搜索时使用不同的分析器是合理的。 我们可能要想为同义词建索引(例如,所有 quick
出现的地方,同时也为 fast
、 rapid
和 speedy
创建索引)。但在搜索时,我们不需要搜索所有的同义词,取而代之的是寻找用户输入的单词是否是 quick
、 fast
、 rapid
或 speedy
。
为了区分,Elasticsearch 也支持一个可选的 search_analyzer
映射,它仅会应用于搜索时( analyzer
还用于索引时)。还有一个等价的 default_search
映射,用以指定索引层的默认配置。
如果考虑到这些额外参数,一个搜索时的 完整 顺序会是下面这样:
- 查询自己定义的
analyzer
,否则 - 字段映射里定义的
search_analyzer
,否则 - 字段映射里定义的
analyzer
,否则 - 索引设置中名为
default_search
的分析器,默认为 - 索引设置中名为
default
的分析器,默认为 standard
标准分析器