Неточный поиск


(Darkness ) #1

Это возможно в elastic? Мне нужно найти записи с их процентом сходства и минимальным процентом (например, 30%) сходства?

Например, у нас есть входная строка «Hello» и в бд «Hello, world!», «Hello, friends!». В этом случае процент сходства составляет 77,4% и 61,53% соответственно. (через similar_text php вычисляется )

Могу ли я получить записи с их сходством не вычисляя это через пхп, так как если это будет поиск среди тысяч записей будет беда. И установить минимальный процент схожести для поиска?
я использую laravel 5 + драйвер (babenkoivan/scout-elasticsearch-driver)
properties' => ['text' => [ 'type' => 'text', 'fields' => [ 'raw' => [ 'type' => 'keyword', ] ] ],
upd
мне удалось добиться более подходящего результата
'must'=>[
'match'=>[
'text'=>[
"fuzziness"=>'AUTO',
'query'=>$query,
]
],
],
но как указать минимальный процент схожести?


(Igor Motov) #2

Это возможно, но очень неоптимально. А можно поинтересоваться, откуда такие странные требования для схожести? Какова конечная цель?


(Darkness ) #3

Да конечно.
У меня есть таблица "works" в ней имя типа работы и цена. Записей будет миллионы.
И будет приходить какой то прайс лист с работами. Нужно пройтись по нему и для каждой работы найти максимально похожее значение из типа работы в бд. Например есть в бд "установка розетки 1шт.", а в прайс листе "установить розетку бла бла бла ...". Соответственно нужно найти эту запись и узнать насколько процентов они схожи и задать минимальный процент. Но нужно еще учесть что эти две записи сейчас примерно на 60% но если строка "установить розетку бла бла бла ..." увеличиться в N раз и не на слова "установить розетку" то процент будет другой, но она то подходит и в итоге из за того что много других слов может попросту отпасть.


(Igor Motov) #4

Ну это похоже не нормальный поиск, вот только алгоритм совпадения не очень понятен. Может лучше считать совпадения по словам (возможно с некоторым количеством ошибок) а не по буквам - так будет гораздо быстрее. Другими словами, вам нужен поиск, который возвращал-бы самые похожие документы или вам нужен поиск, который рассчитывал-бы совпадения по вашему алгоритму?


(Mikhail Khludnev) #5

Делал такое с фонетическим фильтром BMPM и min_should_match. Первый даёт совпадения различных форм слова, второй позволяет отрезать слабые совпадения по словам.
Ещё есть More Like This (MLT) он работает когда нужно искать документ по документу. И да. Точно как в ПХП не будет.


(Darkness ) #6

Да, по словам наверное будет сделать поиск лучше чем по символам. Тогда например той же розетке "установка розетки 1шт. " и то что ищем "установить розетку бла бла бла ..." будет совпадения двух слов будет ~77%


(Igor Motov) #7

Тогда я бы начал с чего-нибудь простого вроде:

DELETE test
PUT test
{
  "settings": {
    "analysis": {
      "filter": {
        "russian_stemmer": {
          "type": "stemmer",
          "language": "russian"
        }
      },
      "analyzer": {
        "russian": {
          "tokenizer": "standard",
          "filter": [
            "lowercase",
            "russian_stemmer"
          ]
        }
      }
    }
  },
  "mappings": {
    "_doc": {
      "properties": {
        "text": {
          "type": "text",
          "analyzer": "russian"
        }
      }
    }
  }
}

PUT test/_doc/1
{
  "text": "установка розетки 1шт."
}


PUT test/_doc/2
{
  "text": "установить розетку бла бла бла ..."
}


GET test/_search?search_type=dfs_query_then_fetch
{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "text": "установка розетки 1шт."
          }
        },
        {
          "match": {
            "text": {
              "query": "установка розетки 1шт.",
              "fuzziness": 2,
              "boost": 0.5
            }
          }
        }
      ]
    }
  }
}

(Darkness ) #8

Ну вроде ищет только я не пойму почему если строки одинаковые то выдает ее соответственно но если строка поиска "Розетка информационная" и в бд есть такие строки "Розетка информационная 45x22.5mm ", "Телефонная панель 50 портов ", "Розетка RJ-45, одинарная, категория 5е.", то первый результат "Розетка информационная 45x22.5mm " а второй почему то "Телефонная панель 50 портов" а не "Розетка RJ-45, одинарная, ...."


(leov) #9

прямо чудо какое-то!!! искусственный интеллект прямо
просекает что там 50 портов а тут всего одинарная
:grinning:


(Mikhail Khludnev) #10

explainAPI ?


(Darkness ) #11

вы не правильно поняли в искомом слове есть "Розетка " и в исходном но почему то алгоритм посчитал что не важно что оно есть там и там выбрал другой вариант менее похожий "Телефонная панель 50 портов" никак не более подходящий вариант к "Розетка информационная" хотя есть вариант с одинаковым вообще словом "Розетка RJ-45, одинарная, категория 5е."


(Igor Motov) #12

Надо смотреть что explain выдает. Возможно, что какой-то термин редкий - и он получает приоритет.