Эффективный поиск в трехуровневой иерархии - PullRequest
0 голосов
/ 08 апреля 2009

Допустим, у меня есть иерархия FirstName> MiddleName> LastName (~ 10 тыс. Строк, ради вопроса). Это означает, что у вас может быть строка «Джон> Мэри-Энн> Эдди» или «Эдди> Джон> Джейкоб». Дело в том, что иерархия не имеет большого смысла и очень чужды пользователю (в отличие, скажем, от страны> штата> структуры города).

Поскольку он настолько неструктурирован и запутан, я хочу предоставить пользователю окно автозаполнения. По мере ввода он должен искать возможные совпадения подстрок, а когда они «рутируют» строку поиска на уровне, он ограничивает результаты до уровня ниже этого уровня.

Теперь, поскольку есть много людей по имени "Джон", нет никакого смысла в том, что если они наберут "Джон", они получат только результаты, такие как

  • Джон> Аллен> Александр
  • Джон> Аллен> Буршавиц
  • Джон> Аллен ... повторить 100 раз ...

Потому что они никогда не увидят уникальную строку «Джейсон> Джон> Смит».

Вместо этого они должны получить что-то вроде («*» - это просто произвольный индикатор для пользователя «эй, намного больше строк под этим существует»):

  • Джон> Аллен> *
  • Джейсон> Джон> Смит
  • Майк> Джон> *
  • Мэри> Елена> Джонсон

Если они наберут "John> Al", то результаты будут ограничены чем-либо из "John>", но должны быть сгруппированы аналогично приведенному выше.

Надеюсь, объяснение понятно. Требования немного свободны. Только разумные, чтобы человек мог искать по дереву и находить то, что ему нужно.

Сейчас у меня есть интересный SQL, который ищет поисковый запрос в строке, выясняет его положение, выполняет некоторые подстроки, группирует и упорядочивает их, чтобы получить вышеуказанные результаты, но он не работает достаточно хорошо .

Я пытаюсь решить эту проблему на типичном стеке LAMP (кроме Oracle). Это не общий хостинг, поэтому у меня есть полный контроль над сервером. Данные меняются небольшими количествами каждые несколько недель, и результаты поиска могут оставаться устаревшими в течение разумного периода времени (например, не может быть и речи о кроне, который обновляет поисковый индекс).

1 Ответ

0 голосов
/ 09 апреля 2009

Argh. Извините, я не смог описать мою проблему. В любом случае, вот решение, которое я придумала.

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

например. Из mytable(A, B, C) создайте search_t(A, B, C, level)

Итак, с помощью «One> Two> Three» вы создаете 3 строки (A, B, C, level):

  • «Один», ноль, ноль, 1
  • «Один», «Два», ноль, 2
  • «Один», «Два», «Три», 3

При поиске можно ограничить уровень, выбрав значение для уровня и указав значения для столбцов верхнего уровня:

WHERE A='One' and level > 1 and (B like '%t%' or C like '%t')

Это может быть немного упрощено и универсально, если вы создаете столбец search_str и вместо этого выполняете сопоставление LIKE.

WHERE A='One' and level > 1 and search_str like '%t%'

В ретроспективе это, вероятно, было бы более очевидно, если бы данные уже были в модели списка смежности.

...