控制分析edit

查询只能查找倒排索引表中真实存在的项,所以保证文档在索引时与查询字符串在搜索时应用相同的分析过程非常重要,这样查询的项才能够匹配倒排索引中的项。

尽管是在说 文档 ,不过分析器可以由每个字段决定。每个字段都可以有不同的分析器,既可以通过配置为字段指定分析器,也可以使用更高层的类型(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 查询为每个字段使用合适的分析器,以保证它在寻找每个项时都为该字段使用正确的格式。

默认分析器edit

虽然我们可以在字段层级指定分析器,但是如果该层级没有指定任何的分析器,那么我们如何能确定这个字段使用的是哪个分析器呢?

分析器可以从三个层面进行定义:按字段(per-field)、按索引(per-index)或全局缺省(global default)。Elasticsearch 会按照以下顺序依次处理,直到它找到能够使用的分析器。索引时的顺序如下:

  • 字段映射里定义的 analyzer ,否则
  • 索引设置中名为 default 的分析器,默认为
  • standard 标准分析器

在搜索时,顺序有些许不同:

  • 查询自己定义的 analyzer ,否则
  • 字段映射里定义的 analyzer ,否则
  • 索引设置中名为 default 的分析器,默认为
  • standard 标准分析器

有时,在索引时和搜索时使用不同的分析器是合理的。我们可能要想为同义词建索引(例如,所有 quick 出现的地方,同时也为 fastrapidspeedy 创建索引)。但在搜索时,我们不需要搜索所有的同义词,取而代之的是寻找用户输入的单词是否是 quickfastrapidspeedy

为了区分,Elasticsearch 也支持一个可选的 search_analyzer 映射,它仅会应用于搜索时( analyzer 还用于索引时)。还有一个等价的 default_search 映射,用以指定索引层的默认配置。

如果考虑到这些额外参数,一个搜索时的 完整 顺序会是下面这样:

  • 查询自己定义的 analyzer ,否则
  • 字段映射里定义的 search_analyzer ,否则
  • 字段映射里定义的 analyzer ,否则
  • 索引设置中名为 default_search 的分析器,默认为
  • 索引设置中名为 default 的分析器,默认为
  • standard 标准分析器

分析器配置实践edit

就可以配置分析器地方的数量而言是十分惊人的,但是实际非常简单。

保持简单edit

多数情况下,会提前知道文档会包括哪些字段。最简单的途径就是在创建索引或者增加类型映射时,为每个全文字段设置分析器。这种方式尽管有点麻烦,但是它让我们可以清楚的看到每个字段每个分析器是如何设置的。

通常,多数字符串字段都是 not_analyzed 精确值字段,比如标签(tag)或枚举(enum),而且更多的全文字段会使用默认的 standard 分析器或 english 或其他某种语言的分析器。这样只需要为少数一两个字段指定自定义分析:或许标题 title 字段需要以支持 输入即查找(find-as-you-type) 的方式进行索引。

可以在索引级别设置中,为绝大部分的字段设置你想指定的 default 默认分析器。然后在字段级别设置中,对某一两个字段配置需要指定的分析器。

对于和时间相关的日志数据,通常的做法是每天自行创建索引,由于这种方式不是从头创建的索引,仍然可以用 索引模板(Index Template) 为新建的索引指定配置和映射。