词语分隔图标记过滤器

编辑

在非字母数字字符处分割标记。word_delimiter_graph 过滤器还根据一组规则执行可选的标记规范化。默认情况下,过滤器使用以下规则:

  • 在非字母数字字符处分割标记。过滤器使用这些字符作为分隔符。例如:Super-DuperSuperDuper
  • 删除每个标记开头或结尾的分隔符。例如:XL---42+'Autocoder'XL42Autocoder
  • 在字母大小写转换处分割标记。例如:PowerShotPowerShot
  • 在字母-数字转换处分割标记。例如:XL500XL500
  • 删除每个标记末尾的英语所有格 ('s)。例如:Neil'sNeil

word_delimiter_graph 过滤器使用 Lucene 的 WordDelimiterGraphFilter

word_delimiter_graph 过滤器旨在删除复杂标识符(例如产品 ID 或零件号)中的标点符号。对于这些用例,我们建议将 word_delimiter_graph 过滤器与 keyword 分词器一起使用。

避免使用 word_delimiter_graph 过滤器分割连字符单词,例如 wi-fi。由于用户经常搜索带有和不带有连字符的这些单词,我们建议改用 synonym_graph 过滤器。

示例

编辑

以下 analyze API 请求使用 word_delimiter_graph 过滤器,根据过滤器的默认规则将 Neil's-Super-Duper-XL500--42+AutoCoder 分割成规范化的标记

resp = client.indices.analyze(
    tokenizer="keyword",
    filter=[
        "word_delimiter_graph"
    ],
    text="Neil's-Super-Duper-XL500--42+AutoCoder",
)
print(resp)
response = client.indices.analyze(
  body: {
    tokenizer: 'keyword',
    filter: [
      'word_delimiter_graph'
    ],
    text: "Neil's-Super-Duper-XL500--42+AutoCoder"
  }
)
puts response
const response = await client.indices.analyze({
  tokenizer: "keyword",
  filter: ["word_delimiter_graph"],
  text: "Neil's-Super-Duper-XL500--42+AutoCoder",
});
console.log(response);
GET /_analyze
{
  "tokenizer": "keyword",
  "filter": [ "word_delimiter_graph" ],
  "text": "Neil's-Super-Duper-XL500--42+AutoCoder"
}

过滤器生成以下标记

[ Neil, Super, Duper, XL, 500, 42, Auto, Coder ]

添加到分析器

编辑

以下 create index API 请求使用 word_delimiter_graph 过滤器配置一个新的 自定义分析器

resp = client.indices.create(
    index="my-index-000001",
    settings={
        "analysis": {
            "analyzer": {
                "my_analyzer": {
                    "tokenizer": "keyword",
                    "filter": [
                        "word_delimiter_graph"
                    ]
                }
            }
        }
    },
)
print(resp)
response = client.indices.create(
  index: 'my-index-000001',
  body: {
    settings: {
      analysis: {
        analyzer: {
          my_analyzer: {
            tokenizer: 'keyword',
            filter: [
              'word_delimiter_graph'
            ]
          }
        }
      }
    }
  }
)
puts response
const response = await client.indices.create({
  index: "my-index-000001",
  settings: {
    analysis: {
      analyzer: {
        my_analyzer: {
          tokenizer: "keyword",
          filter: ["word_delimiter_graph"],
        },
      },
    },
  },
});
console.log(response);
PUT /my-index-000001
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_analyzer": {
          "tokenizer": "keyword",
          "filter": [ "word_delimiter_graph" ]
        }
      }
    }
  }
}

避免将 word_delimiter_graph 过滤器与删除标点符号的分词器(例如 standard 分词器)一起使用。这可能会阻止 word_delimiter_graph 过滤器正确分割标记。它还可能会干扰过滤器的可配置参数,例如 catenate_allpreserve_original。我们建议改用 keywordwhitespace 分词器。

可配置参数

编辑
adjust_offsets

(可选,布尔值)如果为 true,则过滤器调整分割或连接标记的偏移量,以更好地反映它们在标记流中的实际位置。默认为 true

如果你的分析器使用了过滤器(例如 trim 过滤器),这些过滤器会更改标记的长度而不更改其偏移量,请将 adjust_offsets 设置为 false。否则,word_delimiter_graph 过滤器可能会生成具有非法偏移量的标记。

catenate_all

(可选,布尔值)如果为 true,则过滤器会为非字母分隔符分隔的字母数字字符链生成连接的标记。例如:super-duper-xl-500 → [ superduperxl500, super, duper, xl, 500 ]。默认为 false

将此参数设置为 true 会生成多位置标记,索引不支持多位置标记。

如果此参数为 true,请避免在索引分析器中使用此过滤器,或者在此过滤器之后使用 flatten_graph 过滤器,以使标记流适合索引。

当用于搜索分析时,连接的标记可能会给 match_phrase 查询和其他依赖标记位置进行匹配的查询带来问题。如果你计划使用这些查询,请避免将此参数设置为 true

catenate_numbers

(可选,布尔值)如果为 true,则过滤器会为非字母分隔符分隔的数字字符链生成连接的标记。例如:01-02-03 → [ 010203, 01, 02, 03 ]。默认为 false

将此参数设置为 true 会生成多位置标记,索引不支持多位置标记。

如果此参数为 true,请避免在索引分析器中使用此过滤器,或者在此过滤器之后使用 flatten_graph 过滤器,以使标记流适合索引。

当用于搜索分析时,连接的标记可能会给 match_phrase 查询和其他依赖标记位置进行匹配的查询带来问题。如果你计划使用这些查询,请避免将此参数设置为 true

catenate_words

(可选,布尔值)如果为 true,则过滤器会为非字母分隔符分隔的字母字符链生成连接的标记。例如:super-duper-xl → [ superduperxl, super, duper, xl ]。默认为 false

将此参数设置为 true 会生成多位置标记,索引不支持多位置标记。

如果此参数为 true,请避免在索引分析器中使用此过滤器,或者在此过滤器之后使用 flatten_graph 过滤器,以使标记流适合索引。

当用于搜索分析时,连接的标记可能会给 match_phrase 查询和其他依赖标记位置进行匹配的查询带来问题。如果你计划使用这些查询,请避免将此参数设置为 true

generate_number_parts
(可选,布尔值)如果为 true,则过滤器会在输出中包含仅由数字字符组成的标记。如果为 false,则过滤器会将这些标记从输出中排除。默认为 true
generate_word_parts
(可选,布尔值)如果为 true,则过滤器会在输出中包含仅由字母字符组成的标记。如果为 false,则过滤器会将这些标记从输出中排除。默认为 true
ignore_keywords
(可选,布尔值)如果为 true,则过滤器会跳过 keyword 属性为 true 的标记。默认为 false
preserve_original

(可选,布尔值)如果为 true,则过滤器会在输出中包含任何分割标记的原始版本。此原始版本包含非字母数字分隔符。例如:super-duper-xl-500 → [ super-duper-xl-500, super, duper, xl, 500 ]。默认为 false

将此参数设置为 true 会生成多位置标记,索引不支持多位置标记。

如果此参数为 true,请避免在索引分析器中使用此过滤器,或者在此过滤器之后使用 flatten_graph 过滤器,以使标记流适合索引。

protected_words
(可选,字符串数组)过滤器不会分割的标记的数组。
protected_words_path

(可选,字符串)包含过滤器不会分割的标记列表的文件的路径。

此路径必须是绝对路径或相对于 config 位置的路径,并且文件必须是 UTF-8 编码。文件中的每个标记必须以换行符分隔。

split_on_case_change
(可选,布尔值)如果为 true,则过滤器会在字母大小写转换处分割标记。例如:camelCase → [ camel, Case ]。默认为 true
split_on_numerics
(可选,布尔值)如果为 true,则过滤器会在字母-数字转换处分割标记。例如:j2se → [ j, 2, se ]。默认为 true
stem_english_possessive
(可选,布尔值)如果为 true,则过滤器会删除每个标记末尾的英语所有格 ('s)。例如:O'Neil's → [ O, Neil ]。默认为 true
type_table

(可选,字符串数组)字符的自定义类型映射的数组。这允许你将非字母数字字符映射为数字或字母数字,以避免在这些字符上分割。

例如,以下数组将加号 (+) 和连字符 (-) 字符映射为字母数字,这意味着它们不会被视为分隔符

[ "+ => ALPHA", "- => ALPHA" ]

支持的类型包括

  • ALPHA(字母)
  • ALPHANUM(字母数字)
  • DIGIT(数字)
  • LOWER(小写字母)
  • SUBWORD_DELIM(非字母数字分隔符)
  • UPPER(大写字母)
type_table_path

(可选,字符串)包含字符的自定义类型映射的文件的路径。这允许你将非字母数字字符映射为数字或字母数字,以避免在这些字符上分割。

例如,此文件的内容可能包含以下内容

# Map the $, %, '.', and ',' characters to DIGIT
# This might be useful for financial data.
$ => DIGIT
% => DIGIT
. => DIGIT
\\u002C => DIGIT

# in some cases you might not want to split on ZWJ
# this also tests the case where we need a bigger byte[]
# see https://en.wikipedia.org/wiki/Zero-width_joiner
\\u200D => ALPHANUM

支持的类型包括

  • ALPHA(字母)
  • ALPHANUM(字母数字)
  • DIGIT(数字)
  • LOWER(小写字母)
  • SUBWORD_DELIM(非字母数字分隔符)
  • UPPER(大写字母)

此文件路径必须是绝对路径或相对于 config 位置的路径,并且文件必须是 UTF-8 编码。文件中的每个映射必须以换行符分隔。

自定义

编辑

要自定义 word_delimiter_graph 过滤器,请复制它以创建一个新的自定义标记过滤器的基础。你可以使用其可配置参数修改过滤器。

例如,以下请求创建一个 word_delimiter_graph 过滤器,该过滤器使用以下规则

  • 在非字母数字字符处分割标记,除了 连字符 (-) 字符。
  • 删除每个标记开头或结尾的分隔符。
  • 不要在字母大小写转换处分割标记。
  • 不要在字母-数字转换处分割标记。
  • 删除每个标记末尾的英语所有格 ('s)。
resp = client.indices.create(
    index="my-index-000001",
    settings={
        "analysis": {
            "analyzer": {
                "my_analyzer": {
                    "tokenizer": "keyword",
                    "filter": [
                        "my_custom_word_delimiter_graph_filter"
                    ]
                }
            },
            "filter": {
                "my_custom_word_delimiter_graph_filter": {
                    "type": "word_delimiter_graph",
                    "type_table": [
                        "- => ALPHA"
                    ],
                    "split_on_case_change": False,
                    "split_on_numerics": False,
                    "stem_english_possessive": True
                }
            }
        }
    },
)
print(resp)
response = client.indices.create(
  index: 'my-index-000001',
  body: {
    settings: {
      analysis: {
        analyzer: {
          my_analyzer: {
            tokenizer: 'keyword',
            filter: [
              'my_custom_word_delimiter_graph_filter'
            ]
          }
        },
        filter: {
          my_custom_word_delimiter_graph_filter: {
            type: 'word_delimiter_graph',
            type_table: [
              '- => ALPHA'
            ],
            split_on_case_change: false,
            split_on_numerics: false,
            stem_english_possessive: true
          }
        }
      }
    }
  }
)
puts response
const response = await client.indices.create({
  index: "my-index-000001",
  settings: {
    analysis: {
      analyzer: {
        my_analyzer: {
          tokenizer: "keyword",
          filter: ["my_custom_word_delimiter_graph_filter"],
        },
      },
      filter: {
        my_custom_word_delimiter_graph_filter: {
          type: "word_delimiter_graph",
          type_table: ["- => ALPHA"],
          split_on_case_change: false,
          split_on_numerics: false,
          stem_english_possessive: true,
        },
      },
    },
  },
});
console.log(response);
PUT /my-index-000001
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_analyzer": {
          "tokenizer": "keyword",
          "filter": [ "my_custom_word_delimiter_graph_filter" ]
        }
      },
      "filter": {
        "my_custom_word_delimiter_graph_filter": {
          "type": "word_delimiter_graph",
          "type_table": [ "- => ALPHA" ],
          "split_on_case_change": false,
          "split_on_numerics": false,
          "stem_english_possessive": true
        }
      }
    }
  }
}

word_delimiter_graphword_delimiter 之间的差异

编辑

当以下任何参数为 true 时,word_delimiter_graphword_delimiter 过滤器都会生成跨越多个位置的标记:

但是,只有 word_delimiter_graph 过滤器才会为多位置标记分配一个 positionLength 属性,该属性指示标记跨越的位置数。这确保 word_delimiter_graph 过滤器始终生成有效的 标记图

word_delimiter 过滤器不会为多位置标记分配 positionLength 属性。这意味着它会为包含这些标记的流生成无效的图。

虽然索引不支持包含多位置标记的标记图,但诸如 match_phrase 查询之类的查询可以使用这些图从单个查询字符串生成多个子查询。

要查看 word_delimiterword_delimiter_graph 过滤器生成的标记图有何不同,请查看以下示例。

示例

基本标记图

当以下参数为 false 时,word_delimiterword_delimiter_graph 都会为 PowerShot2000 生成以下标记图:

此图不包含多位置标记。所有标记仅跨越一个位置。

token graph basic

带有多个位置标记的 word_delimiter_graph

catenate_wordstrue 时,word_delimiter_graph 过滤器为 PowerShot2000 生成以下标记图。

此图正确地指示了连接的 PowerShot 标记跨越两个位置。

token graph wdg

带有多个位置标记的 word_delimiter

catenate_wordstrue 时,word_delimiter 过滤器为 PowerShot2000 生成以下标记图。

请注意,连接的 PowerShot 标记应该跨越两个位置,但它在标记图中只跨越一个位置,这使其无效。

token graph wd