Агрегация категоризации текста
Многогрупповая агрегация, которая группирует полуструктурированный текст в корзины. Каждое поле text переанализируется с помощью настраиваемого анализатора. Полученные токены затем категоризируются, создавая корзины значений текста с аналогичным форматом. Эта агрегация лучше всего подходит для машиногенерированного текста, например, системных журналов. Для категоризации текста используются только первые 100 проанализированных токенов.
Если у вас выделено значительное количество памяти для JVM, но вы получаете исключения разрыва цепи от этой агрегации, возможно, вы пытаетесь категоризировать текст, который плохо отформатирован для категоризации. Рассмотрите возможность добавления categorization_filters или запуска под sampler, диверсифицированным sampler или случайным sampler, чтобы изучить созданные категории.
Алгоритм, используемый для категоризации, был полностью изменён в версии 8.3.0. В результате эта агрегация не будет работать в кластере смешанных версий, где некоторые узлы находятся на версии 8.3.0 или выше, а другие — на версии, более ранней, чем 8.3.0. Обновите все узлы в вашем кластере до одной и той же версии, если у вас возникла ошибка, связанная с этим изменением.
Параметры
-
categorization_analyzer -
(Необязательно, объект или строка) Анализатор категоризации указывает, как анализируется и токенизируется текст перед его категоризацией. Синтаксис очень похож на тот, который используется для определения
analyzerна точке входа Analyze. Это свойство нельзя использовать одновременно сcategorization_filters.Поле
categorization_analyzerможно указать как строку, так и как объект. Если это строка, она должна ссылаться на встроенный анализатор или на анализатор, добавленный другим плагином. Если это объект, у него есть следующие свойства:Свойства
categorization_analyzer-
char_filter - (массив строк или объектов) Один или несколько фильтров символов. В дополнение к встроенным фильтрам символов, другие плагины могут предоставлять больше фильтров символов. Это свойство необязательно. Если оно не указано, перед категоризацией не применяются никакие фильтры символов. Если вы настраиваете какой-либо другой аспект анализатора и вам нужно получить эквивалент
categorization_filters(которые недопустимы, когда настраивается какой-либо другой аспект анализатора), добавьте их сюда в качестве фильтров замены шаблонов. -
tokenizer - (строка или объект) Название или определение токен-разделителя для использования после применения фильтров символов. Это свойство обязательно, если
categorization_analyzerуказано как объект. Машинное обучение предоставляет токен-разделитель под названиемml_standard, который токенизирует данные таким образом, который, как было установлено, обеспечивает хорошую категоризацию результатов для различных форматов файлов журналов для английских журналов. Если вы хотите использовать этот токен-разделитель, но изменить фильтры символов или токенов, укажите"tokenizer": "ml_standard"в вашемcategorization_analyzer. Дополнительно доступен токен-разделительml_classic, который токенизирует данные так же, как и не настраиваемый токен-разделитель в старых версиях продукта (до 6.2).ml_classicбыл значением по умолчанию для токен-разделителя категоризации в версиях 6.2–7.13, поэтому если вам нужна категоризация, идентичная значению по умолчанию для задач, созданных в этих версиях, укажите"tokenizer": "ml_classic"в вашемcategorization_analyzer.
С Elasticsearch 8.10.0 используется новый номер версии для отслеживания изменений конфигурации и состояния в плагине машинного обучения. Этот новый номер версии не связан с версией продукта и будет увеличиваться независимо.
-
filter - (массив строк или объектов) Один или несколько фильтров токенов. В дополнение к встроенным фильтрам токенов, другие плагины могут предоставлять больше фильтров токенов. Это свойство необязательно. Если оно не указано, перед категоризацией не применяются никакие фильтры токенов.
-
-
categorization_filters - (Необязательно, массив строк) Это свойство ожидает массив регулярных выражений. Выражения используются для фильтрации совпадающих последовательностей из значений поля категоризации. Вы можете использовать эту функциональность для уточнения категоризации, исключая последовательности из рассмотрения при определении категорий. Например, вы можете исключить SQL-запросы, которые появляются в ваших файлах журналов. Это свойство нельзя использовать одновременно с
categorization_analyzer. Если вы хотите определить только простые фильтры регулярных выражений, которые применяются перед токенизацией, установка этого свойства является наиболее простым методом. Если вы также хотите настроить токен-разделитель или фильтрацию после токенизации, используйте свойствоcategorization_analyzerи включите фильтры в качествеpattern_replaceфильтров символов. -
field - (Обязательно, строка) Поле полуструктурированного текста для категоризации.
-
max_matched_tokens - (Необязательно, целое число) Этот параметр сейчас ничего не делает, но допускается для совместимости с исходной реализацией до 8.3.0.
-
max_unique_tokens - (Необязательно, целое число) Этот параметр сейчас ничего не делает, но допускается для совместимости с исходной реализацией до 8.3.0.
-
min_doc_count - (Необязательно, целое число) Минимальное количество документов для корзины, которое будет возвращено в результаты.
-
shard_min_doc_count - (Необязательно, целое число) Минимальное количество документов для корзины, которое будет возвращено фрагментом перед объединением.
-
shard_size - (Необязательно, целое число) Количество корзин категоризации, которые будут возвращены с каждого фрагмента перед объединением всех результатов.
-
similarity_threshold - (Необязательно, целое число, по умолчанию:
70) Минимальный процент весового значения токенов, которые должны совпадать для добавления текста в корзину категории. Должно находиться в пределах от 1 до 100. Чем больше значение, тем уже категории. Большие значения увеличат использование памяти и создадут более узкие категории. -
size - (Необязательно, целое число, по умолчанию:
10) Количество корзин для возврата.
Тело ответа
-
key - (строка) Содержит токены (извлеченные
categorization_analyzer), которые являются общими для всех значений входного поля, включённых в категорию. -
doc_count - (целое число) Количество документов, соответствующих категории.
-
max_matching_length - (целое число) Категории из коротких сообщений, содержащих мало токенов, также могут соответствовать категориям, содержащим много токенов, полученных из гораздо более длинных сообщений.
max_matching_lengthявляется показателем максимальной длины сообщений, которые должны рассматриваться как принадлежащие категории. При поиске сообщений, соответствующих категории, все сообщения, длина которых превышаетmax_matching_length, должны быть исключены. Используйте это поле, чтобы предотвратить поиск членов категории коротких сообщений от соответствия гораздо более длинным сообщениям. -
regex - (строка) Регулярное выражение, которое будет соответствовать всем значениям входного поля, включённых в категорию. Возможны случаи, когда
regexне включает каждый термин изkey, если порядок значений отличается между значениями, включёнными в категорию. Однако в простых случаяхregexбудет упорядоченными термами, сконкатенированными в регулярное выражение, которое допускает произвольные разделы между ними. Не рекомендуется использоватьregexкак основной механизм поиска исходных документов, которые были категоризированы. Поиск с использованием регулярных выражений очень медленный. Вместо этого следует использовать термины в полеkeyдля поиска соответствующих документов, так как поиск по терминам может использовать инвертированный индекс и, следовательно, быть намного быстрее. Однако могут быть ситуации, когда полезно использовать полеregexдля проверки, соответствует ли небольшая группа сообщений, которые не были индексированы, категории, или для подтверждения того, что термины в полеkeyвстречаются в правильном порядке во всех соответствующих документах.
Базовое использование
Переанализ больших наборов результатов потребует много времени и памяти. Эта агрегация должна использоваться совместно с асинхронным поиском. Кроме того, можно использовать агрегацию как дочернюю агрегацию выборки или диверсифицированной выборки. Это обычно улучшит скорость и использование памяти.
Пример:
resp = client.search(
index="log-messages",
filter_path="aggregations",
aggs={
"categories": {
"categorize_text": {
"field": "message"
}
}
},
)
print(resp) const response = await client.search({
index: "log-messages",
filter_path: "aggregations",
aggs: {
categories: {
categorize_text: {
field: "message",
},
},
},
});
console.log(response); POST log-messages/_search?filter_path=aggregations
{
"aggs": {
"categories": {
"categorize_text": {
"field": "message"
}
}
}
} Ответ:
{
"aggregations" : {
"categories" : {
"buckets" : [
{
"doc_count" : 3,
"key" : "Node shutting down",
"regex" : ".*?Node.+?shutting.+?down.*?",
"max_matching_length" : 49
},
{
"doc_count" : 1,
"key" : "Node starting up",
"regex" : ".*?Node.+?starting.+?up.*?",
"max_matching_length" : 47
},
{
"doc_count" : 1,
"key" : "User foo_325 logging on",
"regex" : ".*?User.+?foo_325.+?logging.+?on.*?",
"max_matching_length" : 52
},
{
"doc_count" : 1,
"key" : "User foo_864 logged off",
"regex" : ".*?User.+?foo_864.+?logged.+?off.*?",
"max_matching_length" : 52
}
]
}
}
} Вот пример использования categorization_filters
resp = client.search(
index="log-messages",
filter_path="aggregations",
aggs={
"categories": {
"categorize_text": {
"field": "message",
"categorization_filters": [
"\\w+\\_\\d{3}"
]
}
}
},
)
print(resp) const response = await client.search({
index: "log-messages",
filter_path: "aggregations",
aggs: {
categories: {
categorize_text: {
field: "message",
categorization_filters: ["\\w+\\_\\d{3}"],
},
},
},
});
console.log(response); POST log-messages/_search?filter_path=aggregations
{
"aggs": {
"categories": {
"categorize_text": {
"field": "message",
"categorization_filters": ["\\w+\\_\\d{3}"]
}
}
}
} | Фильтры, применяемые к проанализированным токенам. Он отфильтровывает токены, такие как |
Обратите внимание, как токены foo_<number> не являются частью результатов категории.
{
"aggregations" : {
"categories" : {
"buckets" : [
{
"doc_count" : 3,
"key" : "Node shutting down",
"regex" : ".*?Node.+?shutting.+?down.*?",
"max_matching_length" : 49
},
{
"doc_count" : 1,
"key" : "Node starting up",
"regex" : ".*?Node.+?starting.+?up.*?",
"max_matching_length" : 47
},
{
"doc_count" : 1,
"key" : "User logged off",
"regex" : ".*?User.+?logged.+?off.*?",
"max_matching_length" : 52
},
{
"doc_count" : 1,
"key" : "User logging on",
"regex" : ".*?User.+?logging.+?on.*?",
"max_matching_length" : 52
}
]
}
}
} Вот пример использования categorization_filters. По умолчанию анализатор использует токенизатор ml_standard, который похож на токенизатор по пробелам, но отфильтровывает токены, которые могут быть интерпретированы как шестнадцатеричные числа. По умолчанию анализатор также использует фильтр символов first_line_with_letters, поэтому учитывается только первая значимая строка многострочных сообщений. Однако может быть, что токен является известным высокоизменчивым токеном (форматированные имена пользователей, адреса электронной почты и т. д.). В этом случае полезно предоставить пользовательские categorization_filters для фильтрации таких токенов для лучшей категоризации. Эти фильтры также могут снизить использование памяти, так как в памяти для категорий хранится меньше токенов. (Если есть достаточно примеров разных имен пользователей, адресов электронной почты и т. д., то категории будут формироваться так, чтобы естественным образом отбрасывать их как переменные, но для небольших входных данных, где существует только один пример, этого не произойдет.)
resp = client.search(
index="log-messages",
filter_path="aggregations",
aggs={
"categories": {
"categorize_text": {
"field": "message",
"categorization_filters": [
"\\w+\\_\\d{3}"
],
"similarity_threshold": 11
}
}
},
)
print(resp) const response = await client.search({
index: "log-messages",
filter_path: "aggregations",
aggs: {
categories: {
categorize_text: {
field: "message",
categorization_filters: ["\\w+\\_\\d{3}"],
similarity_threshold: 11,
},
},
},
});
console.log(response); POST log-messages/_search?filter_path=aggregations
{
"aggs": {
"categories": {
"categorize_text": {
"field": "message",
"categorization_filters": ["\\w+\\_\\d{3}"],
"similarity_threshold": 11
}
}
}
} | Фильтры, применяемые к проанализированным токенам. Он отфильтровывает токены, такие как | |
| Требуется 11% весовой части токена для соответствия перед добавлением сообщения в существующую категорию, а не созданием новой. |
Полученные категории теперь очень широкие, объединяющие группы журналов. (Значение similarity_threshold 11% обычно слишком низкое. Значения свыше 50% обычно лучше.)
{
"aggregations" : {
"categories" : {
"buckets" : [
{
"doc_count" : 4,
"key" : "Node",
"regex" : ".*?Node.*?",
"max_matching_length" : 49
},
{
"doc_count" : 2,
"key" : "User",
"regex" : ".*?User.*?",
"max_matching_length" : 52
}
]
}
}
} Эта агрегация может иметь как дочерние агрегации, так и сама быть дочерней агрегацией. Это позволяет собрать лучшие ежедневные категории и лучшие примеры документов, как показано ниже.
resp = client.search(
index="log-messages",
filter_path="aggregations",
aggs={
"daily": {
"date_histogram": {
"field": "time",
"fixed_interval": "1d"
},
"aggs": {
"categories": {
"categorize_text": {
"field": "message",
"categorization_filters": [
"\\w+\\_\\d{3}"
]
},
"aggs": {
"hit": {
"top_hits": {
"size": 1,
"sort": [
"time"
],
"_source": "message"
}
}
}
}
}
}
},
)
print(resp) const response = await client.search({
index: "log-messages",
filter_path: "aggregations",
aggs: {
daily: {
date_histogram: {
field: "time",
fixed_interval: "1d",
},
aggs: {
categories: {
categorize_text: {
field: "message",
categorization_filters: ["\\w+\\_\\d{3}"],
},
aggs: {
hit: {
top_hits: {
size: 1,
sort: ["time"],
_source: "message",
},
},
},
},
},
},
},
});
console.log(response); POST log-messages/_search?filter_path=aggregations
{
"aggs": {
"daily": {
"date_histogram": {
"field": "time",
"fixed_interval": "1d"
},
"aggs": {
"categories": {
"categorize_text": {
"field": "message",
"categorization_filters": ["\\w+\\_\\d{3}"]
},
"aggs": {
"hit": {
"top_hits": {
"size": 1,
"sort": ["time"],
"_source": "message"
}
}
}
}
}
}
}
} {
"aggregations" : {
"daily" : {
"buckets" : [
{
"key_as_string" : "2016-02-07T00:00:00.000Z",
"key" : 1454803200000,
"doc_count" : 3,
"categories" : {
"buckets" : [
{
"doc_count" : 2,
"key" : "Node shutting down",
"regex" : ".*?Node.+?shutting.+?down.*?",
"max_matching_length" : 49,
"hit" : {
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : null,
"hits" : [
{
"_index" : "log-messages",
"_id" : "1",
"_score" : null,
"_source" : {
"message" : "2016-02-07T00:00:00+0000 Node 3 shutting down"
},
"sort" : [
1454803260000
]
}
]
}
}
},
{
"doc_count" : 1,
"key" : "Node starting up",
"regex" : ".*?Node.+?starting.+?up.*?",
"max_matching_length" : 47,
"hit" : {
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : null,
"hits" : [
{
"_index" : "log-messages",
"_id" : "2",
"_score" : null,
"_source" : {
"message" : "2016-02-07T00:00:00+0000 Node 5 starting up"
},
"sort" : [
1454803320000
]
}
]
}
}
}
]
}
},
{
"key_as_string" : "2016-02-08T00:00:00.000Z",
"key" : 1454889600000,
"doc_count" : 3,
"categories" : {
"buckets" : [
{
"doc_count" : 1,
"key" : "Node shutting down",
"regex" : ".*?Node.+?shutting.+?down.*?",
"max_matching_length" : 49,
"hit" : {
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : null,
"hits" : [
{
"_index" : "log-messages",
"_id" : "4",
"_score" : null,
"_source" : {
"message" : "2016-02-08T00:00:00+0000 Node 5 shutting down"
},
"sort" : [
1454889660000
]
}
]
}
}
},
{
"doc_count" : 1,
"key" : "User logged off",
"regex" : ".*?User.+?logged.+?off.*?",
"max_matching_length" : 52,
"hit" : {
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : null,
"hits" : [
{
"_index" : "log-messages",
"_id" : "6",
"_score" : null,
"_source" : {
"message" : "2016-02-08T00:00:00+0000 User foo_864 logged off"
},
"sort" : [
1454889840000
]
}
]
}
}
},
{
"doc_count" : 1,
"key" : "User logging on",
"regex" : ".*?User.+?logging.+?on.*?",
"max_matching_length" : 52,
"hit" : {
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : null,
"hits" : [
{
"_index" : "log-messages",
"_id" : "5",
"_score" : null,
"_source" : {
"message" : "2016-02-08T00:00:00+0000 User foo_325 logging on"
},
"sort" : [
1454889720000
]
}
]
}
}
}
]
}
}
]
}
}
}
© 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/search-aggregations-bucket-categorize-text-aggregation.html