Статьи

Elasticsearch — игнорирование специальных символов в запросе с фильтром замены шаблона и пользовательским анализатором

Используя Elasticsearch 5, у нас было поле, такое как номер водительского удостоверения, где значения могут включать специальные символы и непоследовательное поведение в верхнем / нижнем регистре, поскольку значения вводились пользователями с ограниченной проверкой. Например, это гипотетические значения:

  • CA-123-456-789
  • WI.12345.6789
  • tx123456789
  • аз-123-хуг-456

В нашем приложении конечный пользователь должен искать по этому полю. У нас было деловое требование, чтобы у пользователя не было возможности вводить какие-либо специальные символы, такие как дефисы и точки, чтобы получить запись. Таким образом, для первого примера, приведенного выше, пользователь должен иметь возможность ввести любое из этих значений и увидеть эту запись:

  • CA-123-456-789 (точное совпадение)
  • CA123456789 (без специальных символов)
  • ca123456789 (строчные буквы и без специальных символов)
  • Ca.123.456-789 (смешанные буквы и смешанные специальные символы)

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

Шаг 1: Создать шаблон, заменить символьный фильтр и пользовательский анализатор

Мы определили шаблон замены символов в шаблоне для удаления любых не алфавитно-цифровых символов в индексе следующим образом:

1
2
3
4
5
6
7
"char_filter": {
    "specialCharactersFilter": {
        "pattern": "[^A-Za-z0-9]",
        "type": "pattern_replace",
        "replacement": ""
    }
}

Затем мы использовали этот фильтр для создания собственного анализатора, который мы назвали «alphanumericStringAnalyzer» в индексе:

01
02
03
04
05
06
07
08
09
10
"analyzer": {
    "alphanumericStringAnalyzer": {
        "filter": "lowercase",
        "char_filter": [
            "specialCharactersFilter"
        ],
        "type": "custom",
        "tokenizer": "standard"
    }
}

Шаг 2: Определите сопоставление полей с помощью пользовательского анализатора

Следующим шагом было определение нового отображения поля, в котором использовался новый анализатор «alphanumericStringAnalyzer»:

01
02
03
04
05
06
07
08
09
10
11
12
"driversLicenseNumber": {
    "type": "text",
    "fields": {
        "alphanumeric": {
        "type": "text",
            "analyzer": "alphanumericStringAnalyzer"
        },
        "raw": {
            "type": "keyword"
        }
    }
}

Шаг 3: Запустить запрос к новому полю

В нашем случае мы имеем этот запрос на совпадение как часть логического запроса в предложении «should»:

1
2
3
4
5
6
7
8
9
{
    "match" : {
        "driversLicenseNumber.alphanumeric" : {
            "query" : "Ca.123.456-789",
            "operator" : "OR",
            "boost" : 10.0
        }
    }
}
Опубликовано на Java Code Geeks с разрешения Стивена Уолла, партнера нашей программы JCG . Смотреть оригинальную статью здесь: Elasticsearch — игнорировать специальные символы в запросе с шаблоном замены шаблона и пользовательским анализатором

Мнения, высказанные участниками Java Code Geeks, являются их собственными.