词语分隔符 Token Filter

编辑

我们建议使用 word_delimiter_graph 而不是 word_delimiter 过滤器。

word_delimiter 过滤器可能会产生无效的 Token 图。请参阅 word_delimiter_graphword_delimiter 之间的差异

word_delimiter 过滤器还使用 Lucene 的 WordDelimiterFilter,该过滤器已被标记为已弃用。

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

  • 在非字母数字字符处拆分 Token。过滤器使用这些字符作为分隔符。例如:Super-DuperSuper, Duper
  • 删除每个 Token 的前导或尾随分隔符。例如:XL---42+'Autocoder'XL, 42, Autocoder
  • 在字母大小写转换处拆分 Token。例如:PowerShotPower, Shot
  • 在字母-数字转换处拆分 Token。例如:XL500XL, 500
  • 从每个 Token 的末尾删除英语所有格('s)。例如:Neil'sNeil

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

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

示例

编辑

以下 analyze API 请求使用 word_delimiter 过滤器,使用过滤器的默认规则将 Neil's-Super-Duper-XL500--42+AutoCoder 拆分为规范化的 Token

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

过滤器生成以下 Token

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

添加到分析器

编辑

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

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

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

可配置参数

编辑
catenate_all

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

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

catenate_numbers

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

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

catenate_words

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

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

generate_number_parts
(可选,布尔值)如果为 true,则过滤器会在输出中包含仅由数字字符组成的 Token。如果为 false,则过滤器会从输出中排除这些 Token。默认为 true
generate_word_parts
(可选,布尔值)如果为 true,则过滤器会在输出中包含仅由字母字符组成的 Token。如果为 false,则过滤器会从输出中排除这些 Token。默认为 true
preserve_original
(可选,布尔值)如果为 true,则过滤器会在输出中包含任何拆分 Token 的原始版本。此原始版本包括非字母数字分隔符。例如:super-duper-xl-500 → [ super-duper-xl-500, super, duper, xl, 500 ]。默认为 false
protected_words
(可选,字符串数组)过滤器不会拆分的 Token 数组。
protected_words_path

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

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

split_on_case_change
(可选,布尔值)如果为 true,则过滤器会在字母大小写转换处拆分 Token。例如:camelCase → [ camel, Case ]。默认为 true
split_on_numerics
(可选,布尔值)如果为 true,则过滤器会在字母-数字转换处拆分 Token。例如:j2se → [ j, 2, se ]。默认为 true
stem_english_possessive
(可选,布尔值)如果为 true,则过滤器会从每个 Token 的末尾删除英语所有格('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 过滤器,请复制它以创建新的自定义 Token 过滤器的基础。您可以使用其可配置参数修改过滤器。

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

  • 在非字母数字字符处拆分 Token,连字符(-)字符除外。
  • 删除每个 Token 的前导或尾随分隔符。
  • 不要在字母大小写转换处拆分 Token。
  • 不要在字母-数字转换处拆分 Token。
  • 从每个 Token 的末尾删除英语所有格('s)。
resp = client.indices.create(
    index="my-index-000001",
    settings={
        "analysis": {
            "analyzer": {
                "my_analyzer": {
                    "tokenizer": "keyword",
                    "filter": [
                        "my_custom_word_delimiter_filter"
                    ]
                }
            },
            "filter": {
                "my_custom_word_delimiter_filter": {
                    "type": "word_delimiter",
                    "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_filter'
            ]
          }
        },
        filter: {
          my_custom_word_delimiter_filter: {
            type: 'word_delimiter',
            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_filter"],
        },
      },
      filter: {
        my_custom_word_delimiter_filter: {
          type: "word_delimiter",
          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_filter" ]
        }
      },
      "filter": {
        "my_custom_word_delimiter_filter": {
          "type": "word_delimiter",
          "type_table": [ "- => ALPHA" ],
          "split_on_case_change": false,
          "split_on_numerics": false,
          "stem_english_possessive": true
        }
      }
    }
  }
}