配置文本分析

edit

默认情况下,Elasticsearch 使用 standard 分析器 进行所有文本分析。standard 分析器为您提供了对大多数自然语言和用例的开箱即用支持。如果您选择直接使用 standard 分析器,则无需进一步配置。

如果标准分析器不符合您的需求,请查看并测试 Elasticsearch 的其他内置 内置分析器。内置分析器不需要配置,但其中一些支持可用于调整其行为的选项。例如,您可以使用自定义停用词列表来配置 standard 分析器以进行删除。

如果没有内置的分析器符合您的需求,您可以测试并创建一个自定义分析器。自定义分析器涉及选择和组合不同的分析器组件,使您能够更好地控制整个过程。

测试分析器

edit

The analyze API 是一个非常有用的工具,用于查看分析器生成的术语。可以在请求中内联指定内置分析器:

POST _analyze
{
  "analyzer": "whitespace",
  "text":     "The quick brown fox."
}

API返回以下响应:

{
  "tokens": [
    {
      "token": "The",
      "start_offset": 0,
      "end_offset": 3,
      "type": "word",
      "position": 0
    },
    {
      "token": "quick",
      "start_offset": 4,
      "end_offset": 9,
      "type": "word",
      "position": 1
    },
    {
      "token": "brown",
      "start_offset": 10,
      "end_offset": 15,
      "type": "word",
      "position": 2
    },
    {
      "token": "fox.",
      "start_offset": 16,
      "end_offset": 20,
      "type": "word",
      "position": 3
    }
  ]
}

您还可以测试以下组合:

  • 一个分词器
  • 零个或多个分词过滤器
  • 零个或多个字符过滤器
POST _analyze
{
  "tokenizer": "standard",
  "filter":  [ "lowercase", "asciifolding" ],
  "text":      "Is this déja vu?"
}

API返回以下响应:

{
  "tokens": [
    {
      "token": "is",
      "start_offset": 0,
      "end_offset": 2,
      "type": "<ALPHANUM>",
      "position": 0
    },
    {
      "token": "this",
      "start_offset": 3,
      "end_offset": 7,
      "type": "<ALPHANUM>",
      "position": 1
    },
    {
      "token": "deja",
      "start_offset": 8,
      "end_offset": 12,
      "type": "<ALPHANUM>",
      "position": 2
    },
    {
      "token": "vu",
      "start_offset": 13,
      "end_offset": 15,
      "type": "<ALPHANUM>",
      "position": 3
    }
  ]
}

或者,在特定索引上运行analyze API时,可以引用自定义分析器

PUT my-index-000001
{
  "settings": {
    "analysis": {
      "analyzer": {
        "std_folded": { 
          "type": "custom",
          "tokenizer": "standard",
          "filter": [
            "lowercase",
            "asciifolding"
          ]
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "my_text": {
        "type": "text",
        "analyzer": "std_folded" 
      }
    }
  }
}

GET my-index-000001/_analyze 
{
  "analyzer": "std_folded", 
  "text":     "Is this déjà vu?"
}

GET my-index-000001/_analyze 
{
  "field": "my_text", 
  "text":  "Is this déjà vu?"
}

API返回以下响应:

{
  "tokens": [
    {
      "token": "is",
      "start_offset": 0,
      "end_offset": 2,
      "type": "<ALPHANUM>",
      "position": 0
    },
    {
      "token": "this",
      "start_offset": 3,
      "end_offset": 7,
      "type": "<ALPHANUM>",
      "position": 1
    },
    {
      "token": "deja",
      "start_offset": 8,
      "end_offset": 12,
      "type": "<ALPHANUM>",
      "position": 2
    },
    {
      "token": "vu",
      "start_offset": 13,
      "end_offset": 15,
      "type": "<ALPHANUM>",
      "position": 3
    }
  ]
}

定义一个名为 std_foldedcustom 分析器。

字段 my_text 使用了 std_folded 分析器。

要引用此分析器,analyze API 必须指定索引名称。

通过名称引用分析器。

参考字段 my_text 使用的分析器。

配置内置分析器

edit

内置的分析器可以直接使用,无需任何配置。然而,其中一些分析器支持配置选项以改变它们的行为。例如,标准分析器可以配置为支持一组停用词:

PUT my-index-000001
{
  "settings": {
    "analysis": {
      "analyzer": {
        "std_english": { 
          "type":      "standard",
          "stopwords": "_english_"
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "my_text": {
        "type":     "text",
        "analyzer": "standard", 
        "fields": {
          "english": {
            "type":     "text",
            "analyzer": "std_english" 
          }
        }
      }
    }
  }
}

POST my-index-000001/_analyze
{
  "field": "my_text", 
  "text": "The old brown cow"
}

POST my-index-000001/_analyze
{
  "field": "my_text.english", 
  "text": "The old brown cow"
}

我们定义 std_english 分析器基于 standard 分析器,但配置为移除预定义的英语停用词列表。

字段 my_text 直接使用了 standard 分析器,没有任何配置。此字段不会移除任何停用词。 生成的词项为:[ the, old, brown, cow ]

字段 my_text.english 使用了 std_english 分析器,因此英语停用词将被移除。最终的词项是: [ old, brown, cow ]

创建自定义分析器

edit

当内置的分析器不能满足您的需求时,您可以创建一个自定义分析器,它使用适当的组合:

配置

edit

自定义分析器接受以下参数:

类型

分析器类型。接受 内置分析器类型。对于 自定义分析器,使用 custom 或省略此参数。

分词器

内置或自定义的 tokenizer。 (必需)

字符过滤器

一个可选的数组,包含内置或自定义的 字符过滤器

过滤器

一个可选的数组,包含内置或自定义的 token filters

position_increment_gap

在索引文本值数组时,Elasticsearch会在一个值的最后一个词项和下一个值的第一个词项之间插入一个假的“间隙”,以确保短语查询不会匹配来自不同数组元素的两个词项。默认为100。更多信息请参见position_increment_gap

示例配置

edit

以下是一个结合了以下内容的示例:

PUT my-index-000001
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_custom_analyzer": {
          "type": "custom", 
          "tokenizer": "standard",
          "char_filter": [
            "html_strip"
          ],
          "filter": [
            "lowercase",
            "asciifolding"
          ]
        }
      }
    }
  }
}

POST my-index-000001/_analyze
{
  "analyzer": "my_custom_analyzer",
  "text": "Is this <b>déjà vu</b>?"
}

对于自定义分析器,使用类型自定义或省略类型参数。

上述示例产生以下术语:

[ is, this, deja, vu ]

上一个示例使用了带有默认配置的分词器、分词过滤器和字符过滤器,但可以创建每个的配置版本并在自定义分析器中使用它们。

这是一个更复杂的示例,结合了以下内容:

Character Filter
Tokenizer
Token Filters

这是一个例子:

PUT my-index-000001
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_custom_analyzer": { 
          "char_filter": [
            "emoticons"
          ],
          "tokenizer": "punctuation",
          "filter": [
            "lowercase",
            "english_stop"
          ]
        }
      },
      "tokenizer": {
        "punctuation": { 
          "type": "pattern",
          "pattern": "[ .,!?]"
        }
      },
      "char_filter": {
        "emoticons": { 
          "type": "mapping",
          "mappings": [
            ":) => _happy_",
            ":( => _sad_"
          ]
        }
      },
      "filter": {
        "english_stop": { 
          "type": "stop",
          "stopwords": "_english_"
        }
      }
    }
  }
}

POST my-index-000001/_analyze
{
  "analyzer": "my_custom_analyzer",
  "text": "I'm a :) person, and you?"
}

将索引分配一个默认的自定义分析器,my_custom_analyzer。此分析器使用自定义分词器、字符过滤器和分词过滤器,这些都是在请求中稍后定义的。此分析器还省略了type参数。

定义自定义的 punctuation 分词器。

定义自定义的 emoticons 字符过滤器。

定义自定义的 english_stop 词元过滤器。

上述示例产生以下术语:

[ i'm, _happy_, person, you ]

指定一个分析器

edit

Elasticsearch 提供了多种方式来指定内置或自定义分析器:

保持简洁

在不同层次和不同时间指定分析器的灵活性非常好……​但只有在需要时才使用

在大多数情况下,一个简单的方法效果最好:为每个text字段指定一个分析器,如指定字段的分析器中所述。

这种方法与Elasticsearch的默认行为很好地配合,允许您在索引和搜索时使用相同的分析器。它还允许您通过获取映射API快速查看哪个分析器适用于哪个字段。

如果你通常不为你的索引创建映射,你可以使用索引模板来达到类似的效果。

Elasticsearch 如何确定索引分析器

edit

Elasticsearch 通过按顺序检查以下参数来确定使用哪个索引分析器:

  1. 字段的analyzer映射参数。 参见指定字段的分析器
  2. analysis.analyzer.default索引设置。 参见指定索引的默认分析器

如果未指定这些参数中的任何一个,则使用 standard 分析器

指定字段的分析器

edit

在映射索引时,您可以使用 analyzer 映射参数 为每个 text 字段指定一个分析器。

以下创建索引 API请求将空白分析器设置为标题字段的分析器。

PUT my-index-000001
{
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "analyzer": "whitespace"
      }
    }
  }
}

指定索引的默认分析器

edit

除了字段级别的分析器外,您还可以设置一个备用分析器,使用analysis.analyzer.default设置。

以下创建索引 API请求将simple分析器设置为my-index-000001的备用分析器。

PUT my-index-000001
{
  "settings": {
    "analysis": {
      "analyzer": {
        "default": {
          "type": "simple"
        }
      }
    }
  }
}

Elasticsearch 如何确定搜索分析器

edit

在大多数情况下,指定不同的搜索分析器是不必要的。这样做可能会对相关性产生负面影响,并导致意外的搜索结果。

如果您选择指定一个单独的搜索分析器,我们建议您在生产环境中部署之前,彻底测试您的分析配置

在搜索时,Elasticsearch 通过按顺序检查以下参数来确定使用哪个分析器:

  1. 搜索查询中的analyzer参数。 参见为查询指定搜索分析器
  2. 字段的search_analyzer映射参数。 参见为字段指定搜索分析器
  3. analysis.analyzer.default_search索引设置。 参见为索引指定默认搜索分析器
  4. 字段的analyzer映射参数。 参见为字段指定分析器

如果未指定这些参数中的任何一个,则使用 standard 分析器

指定查询的搜索分析器

edit

在编写全文查询时,您可以使用analyzer参数来指定搜索分析器。如果提供了此参数,它将覆盖任何其他搜索分析器。

以下搜索API请求将stop分析器设置为match查询的搜索分析器。

GET my-index-000001/_search
{
  "query": {
    "match": {
      "message": {
        "query": "Quick foxes",
        "analyzer": "stop"
      }
    }
  }
}

指定字段的搜索分析器

edit

在映射索引时,您可以使用 search_analyzer 映射参数为每个 text 字段指定搜索分析器。

如果提供了搜索分析器,则还必须使用analyzer参数指定索引分析器。

以下创建索引 API请求将simple分析器设置为title字段的搜索分析器。

PUT my-index-000001
{
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "analyzer": "whitespace",
        "search_analyzer": "simple"
      }
    }
  }
}

指定索引的默认搜索分析器

edit

创建索引时,您可以使用analysis.analyzer.default_search设置来设置默认的搜索分析器。

如果提供了搜索分析器,则还必须使用 analysis.analyzer.default 设置指定默认索引分析器。

以下 创建索引 API 请求将 whitespace 分析器设置为 my-index-000001 索引的默认搜索分析器。

PUT my-index-000001
{
  "settings": {
    "analysis": {
      "analyzer": {
        "default": {
          "type": "simple"
        },
        "default_search": {
          "type": "whitespace"
        }
      }
    }
  }
}