N-gram 分词器

编辑

ngram 分词器首先会在遇到指定字符列表中的字符时将文本分解成词,然后会生成每个词的指定长度的 N-grams

N-grams 类似于一个在词语上滑动的窗口 - 指定长度的连续字符序列。它们对于查询不使用空格或者有长复合词的语言(如德语)非常有用。

示例输出

编辑

使用默认设置,ngram 分词器会将初始文本视为单个 token,并生成最小长度为 1,最大长度为 2 的 N-grams。

resp = client.indices.analyze(
    tokenizer="ngram",
    text="Quick Fox",
)
print(resp)
response = client.indices.analyze(
  body: {
    tokenizer: 'ngram',
    text: 'Quick Fox'
  }
)
puts response
const response = await client.indices.analyze({
  tokenizer: "ngram",
  text: "Quick Fox",
});
console.log(response);
POST _analyze
{
  "tokenizer": "ngram",
  "text": "Quick Fox"
}

上面的句子将产生以下词项:

[ Q, Qu, u, ui, i, ic, c, ck, k, "k ", " ", " F", F, Fo, o, ox, x ]

配置

编辑

ngram 分词器接受以下参数:

min_gram

一个 gram 中字符的最小长度。默认为 1

max_gram

一个 gram 中字符的最大长度。默认为 2

token_chars

应该包含在 token 中的字符类别。Elasticsearch 将会分割不属于指定类别的字符。默认为 [] (保留所有字符)。

字符类别可以是以下任何一种:

  • letter —  例如 a, b, ï
  • digit —  例如 37
  • whitespace —  例如 " ""\n"
  • punctuation —  例如 !"
  • symbol —  例如 $
  • custom —  自定义字符,需要使用 custom_token_chars 设置进行设置。

custom_token_chars

应视为 token 一部分的自定义字符。 例如,将其设置为 +-_ 将使分词器将加号、减号和下划线符号视为 token 的一部分。

通常将 min_grammax_gram 设置为相同的值是有意义的。 长度越小,匹配的文档越多,但匹配的质量越低。 长度越长,匹配越具体。 三字组(长度为 3)是一个不错的开始。

索引级别设置 index.max_ngram_diff 控制 max_grammin_gram 之间允许的最大差异。

示例配置

编辑

在此示例中,我们将 ngram 分词器配置为将字母和数字视为 token,并生成三字组(长度为 3 的 grams)。

resp = client.indices.create(
    index="my-index-000001",
    settings={
        "analysis": {
            "analyzer": {
                "my_analyzer": {
                    "tokenizer": "my_tokenizer"
                }
            },
            "tokenizer": {
                "my_tokenizer": {
                    "type": "ngram",
                    "min_gram": 3,
                    "max_gram": 3,
                    "token_chars": [
                        "letter",
                        "digit"
                    ]
                }
            }
        }
    },
)
print(resp)

resp1 = client.indices.analyze(
    index="my-index-000001",
    analyzer="my_analyzer",
    text="2 Quick Foxes.",
)
print(resp1)
response = client.indices.create(
  index: 'my-index-000001',
  body: {
    settings: {
      analysis: {
        analyzer: {
          my_analyzer: {
            tokenizer: 'my_tokenizer'
          }
        },
        tokenizer: {
          my_tokenizer: {
            type: 'ngram',
            min_gram: 3,
            max_gram: 3,
            token_chars: [
              'letter',
              'digit'
            ]
          }
        }
      }
    }
  }
)
puts response

response = client.indices.analyze(
  index: 'my-index-000001',
  body: {
    analyzer: 'my_analyzer',
    text: '2 Quick Foxes.'
  }
)
puts response
const response = await client.indices.create({
  index: "my-index-000001",
  settings: {
    analysis: {
      analyzer: {
        my_analyzer: {
          tokenizer: "my_tokenizer",
        },
      },
      tokenizer: {
        my_tokenizer: {
          type: "ngram",
          min_gram: 3,
          max_gram: 3,
          token_chars: ["letter", "digit"],
        },
      },
    },
  },
});
console.log(response);

const response1 = await client.indices.analyze({
  index: "my-index-000001",
  analyzer: "my_analyzer",
  text: "2 Quick Foxes.",
});
console.log(response1);
PUT my-index-000001
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_analyzer": {
          "tokenizer": "my_tokenizer"
        }
      },
      "tokenizer": {
        "my_tokenizer": {
          "type": "ngram",
          "min_gram": 3,
          "max_gram": 3,
          "token_chars": [
            "letter",
            "digit"
          ]
        }
      }
    }
  }
}

POST my-index-000001/_analyze
{
  "analyzer": "my_analyzer",
  "text": "2 Quick Foxes."
}

上面的示例产生以下词项:

[ Qui, uic, ick, Fox, oxe, xes ]