В elastic есть 2000 документов, которые содержат название бренда
Например:
- Валио
- Nesquick
- Невские берега
- Невские сыры
- Невские
Задача:
использовать elastic для нахождения бренда в передаваемой строке
Например:
передаем в elastic строку >>> "Невские берега пирожные"
должны получить из elastic ответ <<< "Невские берега"
Другие примеры:
передаем >>> невские пирожные
получаем <<< невские (важно: "невские" более релевантный результат, чем "невские берега". Тоесть, алгоритм должен учитывать, что необходимость перестановки букв (из "берега" в "пирожные") должно понижать score)
передаем >>> пирожные берега невские
получаем <<< невские (порядок слов в строке важен)
передаем >>> невс пирож
получаем <<< невские (тут видно, что совпадение лишь относительное. Тоесть, чтобы мы не передали, всегда должен возращаться какой то результат (близко к использованиею ngram) )
Я бы использовал ngram, но на запрос "Невские пирожные" -> более релевантным ответом будет "Невские берега", а не "Невские". Потому что в "Невские берега" больше совпадающих ngram.
Так же, ngram не учитывает порядок слов и запрос "салат берега невские" -> может считать "невские берега" релевантным ответом
Я бы хотел что то ближе к посимвольному сравнению.
На самом деле, я нашел, что Dice coefficient корректно выполняет мою задачу по сравнению строк ( https://en.wikibooks.org/wiki/Algorithm_Implementation/Strings/Dice's_coefficient почти тот же ngram, но с понижением score за не совпадение ngram)
Насколько я понимаю, мне нужно выключать токенизацию (чтобы в полях хранились строки без изменений) и писать собственный скрипт сравнения строк.
Вопрос:
- Я иду по правильному пути, мне действительно стоит писать собственный скрипт сравнения строк?
- Скрипт стоит писать в query (script_score) или "Similarity module" ( https://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules-similarity.html )
Спасибо!
Вот пример моих документов:
#!/bin/bash
HOST="localhost:9200"
INDEX="tmp2509"
TYPE="doc"
curl -X PUT "$HOST/$INDEX?pretty" -H 'Content-Type: application/json' -d'
{
"settings":{
"analysis":{
"analyzer":{
"my_analyzer":{
"type":"custom",
"tokenizer":"keyword"
}
}
}
},
"mappings": {
"'$TYPE'": {
"properties": {
"brandName": {
"type": "text",
"analyzer":"my_analyzer"
}
}
}
}
}
'
curl -XPOST "$HOST/$INDEX/_bulk?pretty" -H "Content-Type: application/x-ndjson" -d '
{ "index" : { "_index" : "'$INDEX'", "_type" : "'$TYPE'", "_id" : "1" } }
{ "brandName" : "невские берега" }
{ "index" : { "_index" : "'$INDEX'", "_type" : "'$TYPE'", "_id" : "2" } }
{ "brandName" : "невские бер" }
{ "index" : { "_index" : "'$INDEX'", "_type" : "'$TYPE'", "_id" : "3" } }
{ "brandName" : "невские" }
{ "index" : { "_index" : "'$INDEX'", "_type" : "'$TYPE'", "_id" : "4" } }
{ "brandName" : "невские сыры" }
{ "index" : { "_index" : "'$INDEX'", "_type" : "'$TYPE'", "_id" : "5" } }
{ "brandName" : "валио" }
{ "index" : { "_index" : "'$INDEX'", "_type" : "'$TYPE'", "_id" : "6" } }
{ "brandName" : "valio" }
{ "index" : { "_index" : "'$INDEX'", "_type" : "'$TYPE'", "_id" : "7" } }
{ "brandName" : "nesquick" }
'
curl -X GET "$HOST/$INDEX/$TYPE/_search?pretty" -H 'Content-Type: application/json' -d'
{
"query": {
"match" : {
"brandName" : "невские пирожные"
}
}
}
'
echo "----------------------------------------------"
echo "Пример для ваших запросов:"
echo "curl -X GET \"$HOST/$INDEX/$TYPE/_search?pretty\" -H 'Content-Type: application/json' -d'
{
\"query\": {
\"match\" : {
\"brandName\" : \"невские пирожные\"
}
}
}
'
"