Spec-Zone.ru › Elasticsearch 8
›Elasticsearch Guide [8.17] ›Анализ текста ›Справочник по токенизаторам

Токенизатор Edge n-gram

Токенизатор edge_ngram сначала разбивает текст на слова всякий раз, когда встречается один из указанных символов, затем он генерирует n-граммы каждого слова, где начало n-граммы привязано к началу слова.

Edge N-граммы полезны для запросов поиск по мере ввода.

Когда вам нужен поиск по мере ввода для текста, имеющего широко известный порядок, например, названия фильмов или песен, токенизатор предложение дополнения является намного более эффективным выбором, чем Edge n-граммы. Edge n-граммы имеют преимущество при попытке автозаполнения слов, которые могут появляться в любом порядке.

Пример вывода

При стандартных настройках токенизатор edge_ngram обрабатывает исходный текст как один токен и генерирует n-граммы с минимальной длиной 1 и максимальной длиной 2:

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

Предложение выше сгенерирует следующие термины:

[ Q, Qu ]

Эти стандартные длины n-грамм практически бесполезны. Вам необходимо настроить параметр edge_ngram перед использованием.

Настройка

Токенизатор edge_ngram принимает следующие параметры:

min_gram
Минимальная длина символов в n-грамме. По умолчанию 1.
max_gram

Максимальная длина символов в n-грамме. По умолчанию 2.

См. Ограничения параметра max_gram.

token_chars

Классы символов, которые должны быть включены в токен. Elasticsearch будет разбивать по символам, которые не принадлежат указанным классам. По умолчанию [] (сохранять все символы).

Классы символов могут быть следующими:

  • letter — например, a, b, ï или 京
  • digit — например, 3 или 7
  • whitespace — например, " " или "\n"
  • punctuation — например, ! или "
  • symbol — например, $ или √
  • custom — пользовательские символы, которые необходимо установить с помощью параметра custom_token_chars.
custom_token_chars
Пользовательские символы, которые должны обрабатываться как часть токена. Например, установка этого значения в +-_ заставит токенизатор рассматривать знак плюс, минус и нижнее подчёркивание как часть токена.

Ограничения параметра max_gram

Значение параметра max_gram токенизатора edge_ngram ограничивает длину символов токенов. При использовании токенизатора edge_ngram с анализатором индекса это означает, что поисковые термины, превышающие длину max_gram, могут не соответствовать никаким индексированным терминам.

Например, если значение max_gram равно 3, поиск по запросу apple не соответствует индексированному термину app.

Для решения этой проблемы можно использовать токен-фильтр truncate с анализатором поиска, чтобы укоротить поисковые термины до длины в max_gram символов. Однако это может привести к возвращению нерелевантных результатов.

Например, если значение max_gram равно 3, а поисковые термины обрезаются до трех символов, поисковый термин apple укорачивается до app. Это означает, что поиск по запросу apple вернёт все индексированные термины, соответствующие app, такие как apply, approximate и apple.

Рекомендуется протестировать оба подхода, чтобы выбрать тот, который лучше всего соответствует вашему сценарию использования и желаемому опыту поиска.

Пример конфигурации

В этом примере мы настраиваем токенизатор edge_ngram для обработки букв и цифр как токенов и для генерации n-грамм с минимальной длиной 2 и максимальной длиной 10:

resp = client.indices.create(
    index="my-index-000001",
    settings={
        "analysis": {
            "analyzer": {
                "my_analyzer": {
                    "tokenizer": "my_tokenizer"
                }
            },
            "tokenizer": {
                "my_tokenizer": {
                    "type": "edge_ngram",
                    "min_gram": 2,
                    "max_gram": 10,
                    "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: 'edge_ngram',
            min_gram: 2,
            max_gram: 10,
            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: "edge_ngram",
          min_gram: 2,
          max_gram: 10,
          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": "edge_ngram",
          "min_gram": 2,
          "max_gram": 10,
          "token_chars": [
            "letter",
            "digit"
          ]
        }
      }
    }
  }
}

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

Приведенный выше пример генерирует следующие термины:

[ Qu, Qui, Quic, Quick, Fo, Fox, Foxe, Foxes ]

Обычно рекомендуется использовать тот же analyzer при индексировании и поиске. В случае токенизатора edge_ngram совет отличается. Использовать токенизатор edge_ngram имеет смысл только при индексировании, чтобы гарантировать, что частичные слова доступны для сопоставления в индексе. При поиске просто ищите введенные пользователем термины, например: Quick Fo.

Ниже приведен пример настройки поля для поиска по мере ввода.

Обратите внимание, что значение max_gram для анализатора индекса равно 10, что ограничивает индексированные термины 10 символами. Поисковые термины не обрезаются, а это значит, что поисковые термины, превышающие 10 символов, могут не соответствовать никаким индексированным терминам.

resp = client.indices.create(
    index="my-index-000001",
    settings={
        "analysis": {
            "analyzer": {
                "autocomplete": {
                    "tokenizer": "autocomplete",
                    "filter": [
                        "lowercase"
                    ]
                },
                "autocomplete_search": {
                    "tokenizer": "lowercase"
                }
            },
            "tokenizer": {
                "autocomplete": {
                    "type": "edge_ngram",
                    "min_gram": 2,
                    "max_gram": 10,
                    "token_chars": [
                        "letter"
                    ]
                }
            }
        }
    },
    mappings={
        "properties": {
            "title": {
                "type": "text",
                "analyzer": "autocomplete",
                "search_analyzer": "autocomplete_search"
            }
        }
    },
)
print(resp)

resp1 = client.index(
    index="my-index-000001",
    id="1",
    document={
        "title": "Quick Foxes"
    },
)
print(resp1)

resp2 = client.indices.refresh(
    index="my-index-000001",
)
print(resp2)

resp3 = client.search(
    index="my-index-000001",
    query={
        "match": {
            "title": {
                "query": "Quick Fo",
                "operator": "and"
            }
        }
    },
)
print(resp3)
response = client.indices.create(
  index: 'my-index-000001',
  body: {
    settings: {
      analysis: {
        analyzer: {
          autocomplete: {
            tokenizer: 'autocomplete',
            filter: [
              'lowercase'
            ]
          },
          autocomplete_search: {
            tokenizer: 'lowercase'
          }
        },
        tokenizer: {
          autocomplete: {
            type: 'edge_ngram',
            min_gram: 2,
            max_gram: 10,
            token_chars: [
              'letter'
            ]
          }
        }
      }
    },
    mappings: {
      properties: {
        title: {
          type: 'text',
          analyzer: 'autocomplete',
          search_analyzer: 'autocomplete_search'
        }
      }
    }
  }
)
puts response

response = client.index(
  index: 'my-index-000001',
  id: 1,
  body: {
    title: 'Quick Foxes'
  }
)
puts response

response = client.indices.refresh(
  index: 'my-index-000001'
)
puts response

response = client.search(
  index: 'my-index-000001',
  body: {
    query: {
      match: {
        title: {
          query: 'Quick Fo',
          operator: 'and'
        }
      }
    }
  }
)
puts response
const response = await client.indices.create({
  index: "my-index-000001",
  settings: {
    analysis: {
      analyzer: {
        autocomplete: {
          tokenizer: "autocomplete",
          filter: ["lowercase"],
        },
        autocomplete_search: {
          tokenizer: "lowercase",
        },
      },
      tokenizer: {
        autocomplete: {
          type: "edge_ngram",
          min_gram: 2,
          max_gram: 10,
          token_chars: ["letter"],
        },
      },
    },
  },
  mappings: {
    properties: {
      title: {
        type: "text",
        analyzer: "autocomplete",
        search_analyzer: "autocomplete_search",
      },
    },
  },
});
console.log(response);

const response1 = await client.index({
  index: "my-index-000001",
  id: 1,
  document: {
    title: "Quick Foxes",
  },
});
console.log(response1);

const response2 = await client.indices.refresh({
  index: "my-index-000001",
});
console.log(response2);

const response3 = await client.search({
  index: "my-index-000001",
  query: {
    match: {
      title: {
        query: "Quick Fo",
        operator: "and",
      },
    },
  },
});
console.log(response3);
PUT my-index-000001
{
  "settings": {
    "analysis": {
      "analyzer": {
        "autocomplete": {
          "tokenizer": "autocomplete",
          "filter": [
            "lowercase"
          ]
        },
        "autocomplete_search": {
          "tokenizer": "lowercase"
        }
      },
      "tokenizer": {
        "autocomplete": {
          "type": "edge_ngram",
          "min_gram": 2,
          "max_gram": 10,
          "token_chars": [
            "letter"
          ]
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "analyzer": "autocomplete",
        "search_analyzer": "autocomplete_search"
      }
    }
  }
}

PUT my-index-000001/_doc/1
{
  "title": "Quick Foxes" 
}

POST my-index-000001/_refresh

GET my-index-000001/_search
{
  "query": {
    "match": {
      "title": {
        "query": "Quick Fo", 
        "operator": "and"
      }
    }
  }
}

Анализатор autocomplete индексирует термины [qu, qui, quic, quick, fo, fox, foxe, foxes].

Анализатор autocomplete_search ищет термины [quick, fo], оба из которых присутствуют в индексе.

© 2023-2025 Elasticsearch
As of September 2024, Elasticsearch is available under a choice of three licenses: the Server Side Public License (SSPL), the Elastic License, or the AGPLv3 (OSI approved).
Elasticsearch and the Elasticsearch logo are trademarks of Elasticsearch B.V., registered in the U.S. and in other countries.
https://www.elastic.co/guide/en/elasticsearch/reference/8.17/analysis-edgengram-tokenizer.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API