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

Фильтр токенов захвата шаблонов

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

Осторожно: Патологические регулярные выражения

Фильтр токенов захвата шаблонов использует Регулярные выражения Java.

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

Узнайте больше о патологических регулярных выражениях и способах их предотвращения.

Например, шаблон:

"(([a-z]+)(\d*))"

при сопоставлении со строкой:

"abc123def456"

сгенерирует токены: [ abc123, abc, 123, def456, def, 456 ]

Если preserve_original установлено в true (значение по умолчанию), то он также сгенерирует исходный токен: abc123def456.

Это особенно полезно для индексирования текста, например, с использованием camelCase, например stripHTML, где пользователь может искать "strip html" или "striphtml":

resp = client.indices.create(
    index="test",
    settings={
        "analysis": {
            "filter": {
                "code": {
                    "type": "pattern_capture",
                    "preserve_original": True,
                    "patterns": [
                        "(\\p{Ll}+|\\p{Lu}\\p{Ll}+|\\p{Lu}+)",
                        "(\\d+)"
                    ]
                }
            },
            "analyzer": {
                "code": {
                    "tokenizer": "pattern",
                    "filter": [
                        "code",
                        "lowercase"
                    ]
                }
            }
        }
    },
)
print(resp)
response = client.indices.create(
  index: 'test',
  body: {
    settings: {
      analysis: {
        filter: {
          code: {
            type: 'pattern_capture',
            preserve_original: true,
            patterns: [
              '(\\p{Ll}+|\\p{Lu}\\p{Ll}+|\\p{Lu}+)',
              '(\\d+)'
            ]
          }
        },
        analyzer: {
          code: {
            tokenizer: 'pattern',
            filter: [
              'code',
              'lowercase'
            ]
          }
        }
      }
    }
  }
)
puts response
const response = await client.indices.create({
  index: "test",
  settings: {
    analysis: {
      filter: {
        code: {
          type: "pattern_capture",
          preserve_original: true,
          patterns: ["(\\p{Ll}+|\\p{Lu}\\p{Ll}+|\\p{Lu}+)", "(\\d+)"],
        },
      },
      analyzer: {
        code: {
          tokenizer: "pattern",
          filter: ["code", "lowercase"],
        },
      },
    },
  },
});
console.log(response);
PUT test
{
   "settings" : {
      "analysis" : {
         "filter" : {
            "code" : {
               "type" : "pattern_capture",
               "preserve_original" : true,
               "patterns" : [
                  "(\\p{Ll}+|\\p{Lu}\\p{Ll}+|\\p{Lu}+)",
                  "(\\d+)"
               ]
            }
         },
         "analyzer" : {
            "code" : {
               "tokenizer" : "pattern",
               "filter" : [ "code", "lowercase" ]
            }
         }
      }
   }
}

При использовании для анализа текста

import static org.apache.commons.lang.StringEscapeUtils.escapeHtml

это сгенерирует токены: [ import, static, org, apache, commons, lang, stringescapeutils, string, escape, utils, escapehtml, escape, html ]

Другой пример — анализ адресов электронной почты:

resp = client.indices.create(
    index="test",
    settings={
        "analysis": {
            "filter": {
                "email": {
                    "type": "pattern_capture",
                    "preserve_original": True,
                    "patterns": [
                        "([^@]+)",
                        "(\\p{L}+)",
                        "(\\d+)",
                        "@(.+)"
                    ]
                }
            },
            "analyzer": {
                "email": {
                    "tokenizer": "uax_url_email",
                    "filter": [
                        "email",
                        "lowercase",
                        "unique"
                    ]
                }
            }
        }
    },
)
print(resp)
response = client.indices.create(
  index: 'test',
  body: {
    settings: {
      analysis: {
        filter: {
          email: {
            type: 'pattern_capture',
            preserve_original: true,
            patterns: [
              '([^@]+)',
              '(\\p{L}+)',
              '(\\d+)',
              '@(.+)'
            ]
          }
        },
        analyzer: {
          email: {
            tokenizer: 'uax_url_email',
            filter: [
              'email',
              'lowercase',
              'unique'
            ]
          }
        }
      }
    }
  }
)
puts response
const response = await client.indices.create({
  index: "test",
  settings: {
    analysis: {
      filter: {
        email: {
          type: "pattern_capture",
          preserve_original: true,
          patterns: ["([^@]+)", "(\\p{L}+)", "(\\d+)", "@(.+)"],
        },
      },
      analyzer: {
        email: {
          tokenizer: "uax_url_email",
          filter: ["email", "lowercase", "unique"],
        },
      },
    },
  },
});
console.log(response);
PUT test
{
   "settings" : {
      "analysis" : {
         "filter" : {
            "email" : {
               "type" : "pattern_capture",
               "preserve_original" : true,
               "patterns" : [
                  "([^@]+)",
                  "(\\p{L}+)",
                  "(\\d+)",
                  "@(.+)"
               ]
            }
         },
         "analyzer" : {
            "email" : {
               "tokenizer" : "uax_url_email",
               "filter" : [ "email", "lowercase",  "unique" ]
            }
         }
      }
   }
}

При использовании указанного выше анализатора для адреса электронной почты:

john-smith_123@foo-bar.com

он сгенерирует следующие токены:

john-smith_123@foo-bar.com, john-smith_123,
john, smith, 123, foo-bar.com, foo, bar, com

Необходимы несколько шаблонов, чтобы разрешить перекрывающиеся захваты, но это также означает, что шаблоны менее плотные и их легче понять.

Примечание: Все токены генерируются в одном и том же положении и с одинаковыми смещениями символов. Это означает, например, что запрос match для john-smith_123@foo-bar.com, использующий этот анализатор, вернёт документы, содержащие любой из этих токенов, даже при использовании оператора and. Кроме того, при использовании подсветки будет подсвечен весь исходный токен, а не только соответствующая подстрока. Например, при запросе по вышеуказанному адресу электронной почты для "smith" будет подсвечено:

  <em>john-smith_123@foo-bar.com</em>

а не:

  john-<em>smith</em>_123@foo-bar.com

© 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-pattern-capture-tokenfilter.html

Spec-Zone.ru

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