Конференция "Базы" » Нечеткий поиск в БД, без особой надежды, впрочем
 
  • [ВладОшин] © (01.07.13 12:40) [0]
    таблицы

    select
    T.NAME||'('||TT.NAME||')',
    S.NAME||'('||ST.NAME||')' ,
    H.HOUSE ||'('||nvl(H.Corpus,'-')||')',
    H.House_Id
    from
    main.t_town T
    join main.t_Town_Type   TT on TT.TYPE_TOWN_ID = T.TYPE_TOWN_ID
    join main.t_streets_ref S on S.Town_Id = T.TOWN_ID
    join main.t_street_type ST on ST.TYPE_STREET_ID = S.TYPE_STREET_ID
    join main.o_houses      H on H.STREET_ID = S.STREET_ID

    НИЖНИЙ НОВГОРОД(ГОРОД) ЛЕСНОЙ ГОРОДОК(УЛИЦА) 1(-) 20745
    НИЖНИЙ НОВГОРОД(ГОРОД) ЛЕСНОЙ ГОРОДОК(УЛИЦА) 1(1) 105375921
    НИЖНИЙ НОВГОРОД(ГОРОД) ЛЕСНОЙ ГОРОДОК(УЛИЦА) 1(2) 105375922


    требуется сделать:

    на входе имя
    НИЖНИЙ НОВГОРОД(ГОРОД) ЛЕСНОЙ ГОРОДОК(УЛИЦА) 1(2)
    на выходе id
    105375922  

    на вход может подаваться с ошибками и вообще, как угодно
    Нижний Новгрод, Лесной город, 1
    или
    г. Н. Новгрод; ул. Лесной город; д.1
    или как угодно вообще. Человек различит.  

    Задача сделать программно.. Готовые решения глянуть есть какие?
  • [ВладОшин] © (01.07.13 12:46) [1]
    Лопиталя применить - первое, что приходит. Но к чему?
    Как в строке понять где город, а где улица.. А если город еще и двухспальный :) то вообще не понятно, это уже улица или еще город. Аналогично с улицей..
  • [ВладОшин] © (01.07.13 12:47) [2]
    Да блин, Левенштейна(, не Лопиталя, уже второй раз, блин :))
  • [ВладОшин] © (01.07.13 12:58) [3]
    Блин, совсем без формальных разделителей, очевидно, никак.
    да и вообще, не понятно.

    Если:
    Потребовать, хотя бы что-то, в качестве разделителя
    например, любой из символов .,; и т.п.

    И построить индекс по таблицам по функции Левенштейна. Результаты отсортировать по индексу, ввести параметр максимального расстояния

    MyGetID('ННовгрод, Лесной город, 1', 5) - первые 5 результатов
    где город похож на 'ННовгрод'
    и в каждом случае первые 5 результатов, где улица должна быть похожа на 'Лесной город'
    и в каждом случае первые 5 результатов, где дом должен быть похож на '1'

    Ерунда..
    получится 125 записей.
    Если ошибка при оценке в городе - уже первые 25 записей не корректны.
    а дальше первых 10-20 и не посмотрят...
  • картман © (01.07.13 14:14) [4]

    > Блин, совсем без формальных разделителей, очевидно, никак.

    не в БД только если
  • [ВладОшин] © (01.07.13 14:39) [5]
    не понял..
    Естественно, разделитель требуем в строке ввода, в БД не храним
    и нужна функция что-то вроде
    Select MyGetID('адрес, набитый как попало') = number (dataset of number)

    или вычисления не в БД?
    ладно, пусть в БД всего 20 городов, 200 улиц и 2000 домов, реально в стринггрид передать. Все делаем на клиенте.
    Как? Как это упростит задачу
  • Jeer © (01.07.13 14:43) [6]
    Разбор ( парсинг ) строк отдельно на клиенте, кластеризация по "похожести", выборка из реляционной БД.
    Либо - Data Mining от монстров.
  • картман © (01.07.13 14:54) [7]

    > или вычисления не в БД?
    > ладно, пусть в БД всего 20 городов, 200 улиц и 2000 домов,
    >  реально в стринггрид передать. Все делаем на клиенте.
    > Как? Как это упростит задачу

    я такое делал для КЛАДРа, >1 млн. записей.
    Суть такова: все разбиваем на отдельные слова. Буква - свой бит. Делаем маски для всех слов и составляем префиксное дерево. В каждом узле лежат слова, подходящие под этот узел, каждому слову соответствует список айдишников. При выборке из дерева, собираем узлы, равные и отличающиеся на заданное кол-во букв(битов). Ну а дальше уж Левенштейн или еще что нравится... Ищет быстро, но некоторые записи долго.
  • [ВладОшин] © (02.07.13 17:49) [8]
    Сделал обычным like, так быстрее

    MyGetID('адрес, набитый как попало', 'разделитель', ошибка)
    разделитель зпт (по умолчанию), или явно указывается необязательным параметром
    ошибка по умолчанию 3, или задается

    MyGetID('город,улица,дом, корпус если есть')
    сначала like по городу,
    если не пусто,
    то  из найденных берем первые три города максимально близких по Левенштейну.
    если пусто - сразу посылаем нафиг

    и т.д. с улицами

    Довольно быстро, в итоге.
    на выходе датасет(pipelined) = id и полный адрес дома

    нравится - ткни в нужный,
    не нравится - передай более точные названия
  • Кщд (03.07.13 08:04) [9]
    >[ВладОшин] ©   (02.07.13 17:49) [8]
    полнотекстовый поиск есть?
  • [ВладОшин] © (03.07.13 09:27) [10]

    > полнотекстовый поиск есть?

    нет, но будет
  • Кщд (03.07.13 10:25) [11]
    >[ВладОшин] ©   (02.07.13 17:49) [8]
    я к тому, что для такого: "...сначала like по городу...", - полнотекстовый поиск(контекстные индексы) - самое то, тем паче, если это Oracle
  • [ВладОшин] © (03.07.13 10:39) [12]

    > полнотекстовый поиск(контекстные индексы) -самое то, тем паче, если это Oracle

    Ага, перепрочитал про него - "полнотекстовый поиск"
    К сожалению, не хозяин схемы

    админам написал, что бы был такой :)
    т.ч. или будет, что вероятнее,
         или пусть так остается.
    Мавр свое дело сделал :)
 
Конференция "Базы" » Нечеткий поиск в БД, без особой надежды, впрочем
Есть новые Нет новых   [134430   +2][b:0][p:0.001]