Эластичный поиск многословных перекрывающихся синонимов
Я разработал тезаурус названий должностей и пытаюсь перевести его в формат, совместимый с Elasticsearch.
Моя проблема: синонимы с несколькими словами
Я пытаюсь найти решение для перекрывающихся синонимов из нескольких слов. Когда я обрабатываю задание с названием "Инженер информационной безопасности", я хочу добавить в индекс "Информационная безопасность" и "Инженер безопасности".
Ранее я включил в индекс синонимы информационной безопасности, но обнаружил, что он будет индексировать "Info Security Engineer" как "Info Security" и не будет индексировать "Security Engineer". Из-за этого я удалил из индекса наборы синонимов, такие как "Информационная безопасность".
Сейчас я ищу способ включить синонимы информационной безопасности в индекс.
Несколько вариантов на выбор:
1.) Я мог бы добавить "Инженер информационной безопасности" в качестве синонима "Инженер безопасности", а затем сделать так, чтобы "Инженер безопасности" также был проиндексирован как "Информационная безопасность". Я мог бы добавить синонимы "информационной безопасности" к анализатору и анализатору поиска.
Пример во время индекса:
"synonyms" : [
"security engineer, info security engineer => security_engineer, information_security",
"information security, info security => information_security"
]
Пример во время поиска:
"synonyms" : [
"security engineer, info security engineer => security_engineer, information_security",
"information security, info security => information_security"
]
Убедиться, что синонимы "Инженер безопасности" включают в себя все синонимы "Информационная безопасность", будет трудно реализовать во всем тезаурусе.
2.) "Инженер по безопасности" также может быть проиндексирован как "Информационная безопасность". Я бы добавил синонимы "информационная безопасность" в search_analyzer, чтобы он выполнял поиск по термину "информационная безопасность".
Пример во время индекса:
"synonyms" : [
"security engineer => security_engineer, information_security"
]
Пример во время поиска:
"synonyms" : [
"security engineer => security_engineer",
"information security, info security => information_security"
]
Когда кто-то ищет задания "Информационная безопасность", он возвращает любое из названий заданий, которые были настроены для включения "Информационная безопасность" во время индексации. Однако задания, в названии которых есть фраза типа "Информационная безопасность", но которые не сопоставлены ни с одним из названий заданий по информационной безопасности во время индекса, не будут включены в поиск "Информационная безопасность".
3.) Я мог бы добавить "Информационную безопасность" в search_analyzer и сделать так, чтобы он расширил его до "Инженер безопасности" и любых других заданий по информационной безопасности.
Пример во время индекса:
"synonyms" : [
"security engineer => security_engineer"
]
Пример во время поиска:
"synonyms" : [
"security engineer => security_engineer",
"information security, info security => security_engineer, information_security_analyst, penetration_tester"
]
Это потребует больше усилий для обработки запросов, поскольку будет искать все задания, которые я пометил как задания по информационной безопасности.
4.) Я мог бы исключить использование синонимов во время индекса и использовать только синонимы во время запроса.
Он будет включать все задания, для которых в названии задания предусмотрена защита информации, но не все, где это подразумевается, например, инженер безопасности. Это также делает его более ресурсоемким для обработки запроса.
5.) Я мог бы использовать один индекс для должностей и другой индекс для функций работы, таких как информационная безопасность.
Он будет включать в себя все задания, которые имеют информационную безопасность в названии должности, но будут пропускать подразумеваемые задания. Было бы добавить еще один шаг, чтобы определить, какой индекс использовать.
Как вы думаете?
Любой совет приветствуется. Я пропускаю другие варианты? Проблематично ли расширить на множество терминов во время запроса или во время индекса?
Я склоняюсь к варианту № 2. Я пытаюсь спроектировать его так, чтобы мой тезаурус было легко использовать для систем поиска работы и систем отслеживания кандидатов.
Фон / Текущая настройка
Я создаю индекс вакансий, который использует анализатор и анализатор поиска, который включает синонимы.
curl -XPUT 'http://localhost:9200/jobs/?pretty' -H 'Content-Type: application/json' -d '
{
"settings" : {
"analysis" : {
"filter" : {
"my_job_title_filter_for_index" : {
"type" : "synonym",
"synonyms" : [
"security engineer => security_engineer"
]
},
"my_job_title_filter_for_search" : {
"type" : "synonym",
"synonyms" : [
"security engineer => security_engineer"
]
}
},
"analyzer" : {
"my_job_title_analyzer_for_index" : {
"filter" : [
"standard",
"lowercase",
"stop",
"my_job_title_filter_for_index"
],
"type" : "custom",
"tokenizer" : "standard"
},
"my_job_title_analyzer_for_search" : {
"filter" : [
"standard",
"lowercase",
"stop",
"my_job_title_filter_for_search"
],
"type" : "custom",
"tokenizer" : "standard"
}
}
}
},
"mappings" : {
"job" : {
"properties" : {
"job_title" : {
"type" : "text",
"analyzer" : "my_job_title_analyzer_for_index",
"search_analyzer" : "my_job_title_analyzer_for_search"
}
}
}
}
}
'
Я загружаю данные в индекс:
curl -XPOST 'http://localhost:9200/jobs/job/_bulk?pretty' -H "Content-Type: application/json" -d'
{"index":{"_id":"1"}}
{"job_title":"Security Engineer"}
{"index":{"_id":"2"}}
{"job_title":"Info Security Engineer"}
'
Я запрашиваю данные для инженера по безопасности, и он возвращает оба задания.
curl -XGET 'http://localhost:9200/jobs/job/_search?pretty' -H 'Content-Type: application/json' -d '
{
"query" : {
"match_phrase" : {"job_title" : "security engineer"}
}
}
'
Я запрашиваю индекс для кибербезопасности, и он не возвращает результатов.
curl -XGET 'http://localhost:9200/jobs/job/_search?pretty' -H 'Content-Type: application/json' -d '
{
"query" : {
"match_phrase" : {"job_title" : "cyber security"}
}
}
'
(примечание: я использую как анализатор, так и анализатор поиска, чтобы задания, подобные "SQL DBA", индексировались как "SQL DBA" и "DBA". Затем во время запроса выполняется поиск "SQL DBA". ищет только "SQL DBA", а не "DBA".)