О себе События Портфолио Статьи Гостевая Фотоальбом На злобу дня Ссылки Учеба Программы
Alex_K (г.Киров) - Алексей Кощеев
Хостинг и регистрация доменов в Кирове

Алгоритм объединенного поиска по нескольким источникам информации с постраничной навигацией

Допустим, у нас имеется несколько типов источников информации: тип A (например, статьи), тип B (например, новости), тип C (например, каталог товаров) и т.д.

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

Сделать объединенный поиск без разбивки на страницы тоже нетрудно.

В этой статье я покажу на примере языка Perl, как сделать постраничный вывод информации из нескольких источников.

Пример поиска по сайту с объединением результатов поиска по разным источникам информации с постраничным выводом.

  1. Для каждого источника информации узнаем сколько всего объектов (записей, строк и т.п.) можно извлечь без условия постраничности. Заносим эту информацию в одномерный массив @canBeFound
  2. Формируем массив @limit, который будет содержать третий и четвертый столбец приведенной ниже таблицы. Эта таблица будет содержать по строкам источники информации, а по столбцам следующие значения: 1 - сколько всего может быть найдено объектов без условия постраничности,
    2 - сумма i-ой и всех вышестоящих строк по первому столбцу
    3 - значение ОТ для i-го источника информации (например, это как в MySQL первая цифра LIMIT)
    4 - значение СКОЛЬКО для i-го источника информации (например, это как в MySQL вторая цифра LIMIT)
    Например, для запроса третьей страницы (из трех) с числом результатов поиска 10 на одной странице таблица может иметь вид:
      1 2 3 4
    ист 1 0 0 0 0
    ист 2 10 10 0 0
    ист 3 0 10 0 0
    ист 4 0 10 0 0
    ист 5 12 22 10 2
    ист 6 0 22 0 0
    ист 7 0 22 0 0

    Для первого источника информации нет подходящих объектов.

    Для второго есть 10, но их не нужно выводить, потому что они не "попадают" на третью страницу.

    Для третьего и четвертого источников информации нет подходящих объектов.

    Для пятого есть 12, но показать нужно только 2, пропустив первые 10.

    Для шестого и седьмого источников информации нет подходящих объектов.

  3. Имея массив @limit, делаем соответствующие выборки из источников информации.

Построение массива @limit

# число записей на одной странице my $recordsPerPage = 10; # $page - номер просматриваемой страницы
# с этой записи начинаем выводить
my $start = $recordsPerPage * ($page - 1); my @limit = (); # содержит только ОТ и my $looked = 0; # число "просмотренных" записей, # тех, что нужно показывать для этой страницы my $s = 0; # сумма возможных результатов поиска (столбец 2 таблицы) for (my $i = 0; $i <= $#canBeFound; $i++) { # по всем элементам массива @canBeFound if ( $canBeFound[$i] > 0 ) { if ( $start > $s && $start <= ($s + $canBeFound[$i]) ) { # нашли начало my $l2 = $s + $canBeFound[$i] - $start + 1; my $l1 = $canBeFound[$i] - $l2; $l2 = $recordsPerPage if $l2 > $recordsPerPage; $l1 = 0 if $l1 < 0; $limit[$i] = [$l1, $l2]; $looked += $l2; undef $l2; undef $l1; } else { if ( $looked > 0 ) { # уже что-то находили my $left = $recordsPerPage - $looked; if ( $looked < $recordsPerPage ) { if ( $canBeFound[$i] > $left ) { $limit[$i] = [0, $left]; $looked += $left; } else { $limit[$i] = [0, $canBeFound[$i]]; $looked += $canBeFound[$i]; } } else { $limit[$i] = [0, 0]; } } else { $limit[$i] = [0, 0]; } } } else { $limit[$i] = [0, 0]; } $s += $canBeFound[$i]; } undef $looked; undef $s;

Замечание 1: особенностью такого решения является то, что оно подходит не только для СУБД типа MySQL, но и для других типов хранилищ, например, на основе обычных файлов.

Замечание 2: в MySQL 4.0.0 появилась возможность использования UNION, но до MySQL 4.1.1 типы и размеры полей задавались первой конструкцией SELECT, что лимитировало использование следующих конструкций SELECT, да и число самих извлекаемых полей (столбцов), как правило, от источника к источнику варьируется.

Рекомендую посмотреть также постраничный вывод информации на Яндексе

Алексей Кощеев
13.05.2005
Наверх  Посмотреть другие статьи
Fanshop.ru

Рейтинг@Mail.ru

Rambler's Top100

© Алексей Кощеев, г.Киров, 2001-2024 хостинг предоставлен компанией Айхэд