Разрабатываем функционал поиска по сайту на PHP и MySQL
Одна из самых популярных и необходимых функций на любом сайте – это поиск, реализованный с помощью специальной формы. Этот функционал позволяет посетителям быстро находить на сайте интересующий их контент.
Сегодня мы хотим рассказать, как сделать поиск по сайту с помощью специальной формы, которая будет опрашивать таблицы базы данных и выводить информацию о текущих руководителях на сайте. Вы научитесь создавать таблицы базы данных, которая будет содержать в себе информацию о текущем персонале.
Разрабатывать формы поиска при помощи PHP , а также познакомитесь с SQL ( Structured Query Language ) – специальным языком для сбора, записи и модификации информации, содержащейся в базах данных. Перед тем как начать, рекомендуем вам скачать файлы проекта .
- Инструмент для работы с базами данных MySQL .
- Локальный или удаленный сервер с поддержкой PHP .
- Текстовый редактор.
Создаем базу данных
Если вы не совсем уверены, что сможете разобраться с базой данных на вашем хостинге, то свяжитесь с хостером для получения соответствующих инструкций или помощи. После того как база данных будет создана, вам нужно будет подключить ее, создать таблицу и записать в нее необходимые данные.
Самым популярным инструментом для управления MySQL является PHP My Admin , Этого инструмента будет достаточно для нашего сегодняшнего руководства.
Создание таблицы
Наша таблица должна быть создана в следующем формате:
Column Name | Data Type | Length | Null or Not Null | Primary key? | Auto Increment |
ID | INT | 1 | Not Null | Yes | Yes |
FirstName | Varchar | 50 | Not Null | No | No |
LastName | Varchar | 50 | Not Null | No | No |
Varchar | 50 | Not Null | No | No | |
PhoneNumber | Varchar | 15 | Not Null | No | No |
Таблица базы данных состоит из столбцов и строк, как в Excel . Первый столбец позволяет идентифицировать данные по имени. Далее идет колонка Data types ( тип данных ), которая указывает нам на тип данных, содержащихся в колонке. В поле Length ( Длина ) указывается максимальный объем памяти ( хранилища ) для столбца таблицы. Мы используем переменные, которые дают больше гибкости. Другими словами, если длина ФИО меньше 50 символов, то будет занята лишь часть отведенного места.
И среди данных персонала не может быть пустых значений ( null, empty ). Первая строка выделена желтым цветом, потому что столбец ID – наш основной ключ. Основной ключ в базе данных гарантирует, что каждая запись будет уникальной. К этой колонке также применен автоинкремент, а это значит, что каждой записи в нашей базе данных будет присваиваться уникальный номер автоматически.
Вносим представителей персонала в таблицу
Как только разберетесь с таблицей, начните заполнять ее данными. 6 записей вполне достаточно, чтобы закрепить в уме процедуру. Ниже предлагаю вам собственный пример:
Column ID | FirstName | LastName | PhoneNumber | |
2 | Ryan | Butler | ryanbutler@domain.com | 417-854-8547 |
3 | Brent | Callahan | brentcallahan@domain.com | 417-854-6587 |
Разработка формы
Чтобы создать форму поиска по сайту через Google , откройте любой подходящий текстовый редактор. Я рекомендую воспользоваться бесплатным PSPad . Вы можете использовать любой текстовый редактор, где предусмотрена подсветка синтаксиса. Это в значительной степени облегчит процесс написания и отладки PHP-кода . Создавая страницу для формы поиска, не забудьте сохранить ее в формате .php , иначе PHP-код не будет обрабатываться должным образом. Как только сохраните документ, скопируйте в него следующую разметку:
Если вы знакомы с языком HTML , то тут вам все должно быть понятно как минимум до открывающего тега form . Внутри этого тега находится важнейший элемент всего кода – атрибут action . В качестве действия нашей формы мы указали название нашего файла, а затем применили к нему строку запроса “ go ”.
Проверка на соответствие критерию
Когда пользователь вводит имя или фамилию, а затем нажимает кнопку подтверждения, форма передает данные самой себе и добавляет в конце строку запроса “ go ”. На данном этапе мы проверяем наличие строки запроса go . Если результат положительный, выводим результаты поиска.
До вывода запрашиваемых результатов нам нужно перепроверить: (1) была ли подтверждена форма, (2) содержит ли строка запроса значение go, (3) был ли поисковой запрос введен в нижнем или верхнем регистре? Если ни одна из проверок не дает положительного результата ( true ), то от нас не требуется выполнять какие-либо действия.
Для начала добавим небольшой блок кода PHP поиск по сайту после закрывающего тега :
Сначала мы открываем блок PHP-кода тегом ””.
Любой PHP-код внутри этой пары тегов будет исполняться сервером. Затем мы проверяем, была ли подтверждена форма:
Мы воспользуемся встроенной функцией isset , которая возвращает значение типа bool , и поместим в нее массив $_POST . Логическое выражение в программировании позволяет получить нам либо true , либо false .
Следовательно, если функция возвращает значение true , то форма была подтверждена, и нам нужно продолжить выполнение кода дальше. Если же функция возвращает значение false , то мы выведем сообщение об ошибке. Сохраните весь набранный код в файле search_submit.php .
Далее нам нужно проверить, имеется ли в строке запроса значение go :
Мы вкладываем еще одно условное логическое выражение внутрь основного, но только в этот раз мы используем массив $_GET вместе со значением “ go ”. Сохраните изменения в файле search_go.php .
Теперь нам нужно убедиться, что посетители могут вводить первую букву в строку запроса только в верхнем или только в нижнем регистре. Нам также нужно предусмотреть способ учета критериев поиска, введенных посетителем. Лучше всего проверять введенные посетителем данные с помощью регулярного выражения:
Мы вкладываем еще одно условное логическое выражение внутрь наших двух. На этот раз мы используем регулярное выражение для проверки ввода. Мы используем встроенную функцию preg_match с двумя параметрами: регулярное выражение, и поле формы, к которому должна применяться проверка.
В нашем случае, это будет поле « Имя » ( name ). Чтобы извлечь параметры поиска, указанные посетителем, мы создаем переменную $name, и привязываем к ней значение POST с названием поля из формы, которое будет использоваться в SQL-запросе . Сейчас мы реализовали: (1) отправку данных формы, (2) строка запроса включает значение go и (3) посетитель ввел либо заглавную, либо строчную первую букву. И все эти проверки происходят еще до внесения изменений в базу данных. Сохраните все изменения.
Результаты Connect, Select, Query и Return из таблицы базы данных
Чтобы получить данные из таблицы, сначала в скрипте поиска по сайту нужно подключиться к серверу. Для этого мы используем следующий код:
Мы создаем переменную $db , и привязываем ее к встроенной функции MySQL mysql_connect , которая принимает три параметра: сервер с базой данных ( localhost , если вы работаете локально ), логин и пароль.
После этого мы запускаем встроенную PHP-функцию die , которая останавливает дальнейшее выполнение кода, если нет соединения с базой данных. И выводим информацию об ошибке, запуская встроенную функцию MySQL mysql_error , которая вернет причину ошибки. Сохраните файл search_connectdb.php .
Далее при помощи представленного ниже кода, мы выбираем, какую базу данных использовать:
Создаем переменную под названием mydb и привязываем ее ко встроенной MySQL-функции mysql_select_db , а затем указываем название базы данных, которую создали ранее. Далее мы опрашиваем таблицу базы данных при помощи SQL-запроса с переменной name, в которой содержатся параметры поиска, введенные посетителем:
При опросе таблицы базы данных мы создаем переменную $sql , и привязываем ее к строке, содержащей SQL-запрос . Мы используем оператор SELECT для извлечения значений из столбцов id , а также имени и фамилии из таблицы contacts . Затем мы используем инструкцию WHERE вместе со значениями имени и фамилии, чтобы сузить поиск.
Вместе с оператором LIKE мы используем знак процента (%) – спецсимвол, который возвращает 0 и более знаков, а также переменную name из строки поиска. В результате LIKE ( в сочетании со спецсимволом ) находит любое соответствующее имя в таблице базы данных. Можно описать весь процесс следующим образом: « Мы выбираем имя и фамилию из таблицы contacts , которые соответствуют введенным посетителем ». Сохраните файл search_query.php .
Далее нам нужно поместить результаты SQL-запроса в переменную, и запустить ее при помощи функции mysql_query , как показано ниже:
Мы создаем переменную $result , и присваиваем ей значение функции mysql_query () , внося ее в $query. Теперь наш запрос хранится в переменной result . Чтобы вывести результат в PHP , мы создаем цикл, а затем выводим данные в неупорядоченном списке:
Сначала мы создаем цикл while , внутри него создаем переменную под названием row , и инициализируем ее возвращаемым значением функции mysql_fetch_array , которая принимает переменную result , в которой находится наш SQL-запрос . Внутри цикла while мы присваиваем каждому значению столбца значение переменной с идентичным названием. Затем мы выводим значения внутрь неупорядоченного списка.
Здесь важно обратить внимание на два момента: (1) внутри цикла while не нужно присваивать значения переменным массива row , так как значения можно брать напрямую из массива row ; (2) тег anchor , который мы используем в названии нашего файла вместе с id и основным ключом. Причина этого заключается в том, что во многих поисковых элементах изначально ничего не отображается.
Так как мы показываем только имя и фамилию, приписывая ID в конце нашего тега anchor , то мы можем использовать ID для дополнительного запроса, который позволит вывести дополнительную информацию о персонале. Сохраните файл и протестируйте форму PHP поиска по сайту ( search_display.php ).
Убираем табуляцию
Результаты выводятся в виде неупорядоченного списка, но суть в том, что нам не нужна табуляция. Чтобы избавиться от нее, добавьте следующее CSS-правило в самое начало вашего файла в head :
Поиск по буквам
Для реализации поиска по буквам потребуется лишь несколько дополнительных строк кода. Добавим этот удобный функционал для посетителей. Таким образом, они смогут находить представителей персонала по буквам, которые содержатся в имени или фамилии.
Добавьте следующую строку кода после закрывающего тега form :
Здесь мы изменили четыре фрагмента кода скрипта поиска по сайту:
- Мы используем функцию isset() , и вносим в нее массив $_GET , а затем проверяем значение by ;
- Создаем переменную $letter и инициализируем ее значение массивом $_GET ;
- Добавляем переменную letter в SQL-запрос ;
- Указываем переменную letter внутри выражения, в котором получаем подсчитанное количество строк.
Сохраните файл search_byletter.php и проверьте результат.
Поиск определенного сотрудника
Чтобы отобразить информацию об остальном персонале, которая передается через уникальное id внутри нашей ссылки, нужно добавить следующий код прямо после закрывающей фигурной скобки в скрипте letter , как показано ниже:
Здесь мы изменили четыре фрагмента кода:
- Мы используем функцию isset() , и с ее помощью проверяем значение ID в массиве $_GET ;
- Создаем переменную $contactid и инициализируем ее массивом $_GET ;
- В таблице выделяем все, что отмечено звездочкой * . Звездочка – это сокращенное обозначение в SQL , которое означает « дайте мне все столбцы и строки из таблицы» . Чтобы определить, какую информацию выводить, мы упоминаем переменную contactid в конце SQL-выражения ;
- Выводим дополнительную информацию о каждом представителе персонала.
Сохраните файл search_byid.php и проверьте результат.
Обратите внимание, что наш функционал работает так, как и положено. При вводе имени или фамилии в поле, или при выборе буквы в качестве гиперссылки, отображаются только имена представителей персонала. Если навести курсор на ссылку, то в строке статуса можно увидеть уникальный ID . Если кликнуть по конкретному человеку, то адресная строка изменится, и отобразится дополнительная информация об этом сотруднике.
SQL-инъекция
Причина, по которой мы добавили в наше поле поиска регулярное выражение, заключается в том, чтобы никто не смог вмешаться в наш SQL-запрос . Раньше эта проблема была распространена, и хакеры умудрялись проводить собственные SQL-запросы , манипулируя при этом вашим приложением. Например, если бы мы допустили возможность использовать апостроф в нашем поле, то хакер мог бы просто удалить базу данных, используя запрос:
Как уже было отмечено, регулярное выражение гарантирует, что в качестве первого символа посетитель может вводить лишь буквы в нижнем или верхнем регистре.
В завершение
В сегодняшней статье мы рассмотрели, как сделать поиск по сайту, а также:
- Создавать базы данных и соответствующие таблицы;
- Использовать инструменты для управления базами данных, создавать столбцы и вводить данные;
- Разрабатывать формы поиска на основе PHP , которая умеет осуществлять проверку вводимых данных, наличия переменных в запросе, а также соединяться с базой данных и выводить результаты из таблицы;
- Как защитить приложение и базу данных от SQL-инъекций .
Используя знания, полученные из этой статьи, вы сможете без труда модифицировать чужой код, а также при необходимости расширять функционал формы поиска.
Данная публикация представляет собой перевод статьи « How to Create a Search Feature with PHP and MySQL » , подготовленной дружной командой проекта Интернет-технологии.ру
Источник статьи: http://www.internet-technologies.ru/articles/razrabatyvaem-funkcional-poiska-po-saytu-na-php-i-mysql.html
Создание собственной поисковой системы с помощью PHP
Sphinx индексирует контент, быстро находит текст и выдает полезные результаты поиска
В эпоху Интернета люди хотят, чтобы информация была упакована как фаст-фуд: подавалась моментально, без проблем, и в точно отмеренных порциях. Безусловно, чтобы накормить нетерпеливую и голодную массу, сегодня даже от небольших Web-сайтов ждут широкого выбора блюд с быстрой доставкой:
- RSS — это ваша «служба доставки пиццы», которая приносит свежеиспеченные данные прямо к вашей двери.
- Блог — это ближайший ресторанчик с китайской кухней на вынос, предлагающий ваши любимые острые блюда.
- Форум — это ресторанчик по соседству (если быть более точным, лучше вспомнить сцену битвы едой из фильма «Зверинец»).
- А поиск похож на «съешь, сколько можешь» ночью в местном кафетерии: Просто поставьте на поднос все, чего душа желает, снова и снова, пока это вынесет ваш желудок — и ваш стул.
К счастью, разработчики PHP могут найти множество программного обеспечения для RSS, блогов и форумов, чтобы создать или дополнить свой сайт. И если Google и ему подобные знают практически всё и переваривают огромный трафик, эти поисковые системы не обязательно хорошо подходят ко всем сайтам.
Например, если ваш сайт предлагает сотни тысяч новых и восстановленных запчастей для Porsche, Google может помочь в широких запросах, например, «Carrera parts» («запчасти для Carrera»), но он будет не очень полезен для более точных запросов, например, «used 1991 Porsche 911 Targa headlight bezel» («обрамление подфарника для Porsche 911 Targa 1991 года, б/у»).
Если контент вашего сайта очень специфичен или посетителям вашего сайта нужен поиск, адаптированный к процессам работы самого сайта, лучше всего будет дополнить глобальные поисковые системы локальной, специально созданной для вашего сайта. (Другие примеры специализированного поиска приведены в главе «Иголка в миллиарде стогов сена».)
Узнайте, как добавить на сайт PHP быструю и бесплатную поисковую систему с широкими возможностями и открытым исходным кодом. Здесь разрабатывается лишь малая видимая часть Web-сайта. Основное же внимание уделяется компонентам, необходимым для эффективного поиска: базе данных, индексу, поисковой системе и API-интерфейсу PHP.
Посещение Великого сфинкса
Чтобы реализовать на сайте собственную функцию поиска, нужен источник данных и возможность выполнять поиск по нему. В Web-приложениях источником данных, как правило, выступает реляционная база данных, имеющая некоторые встроенные возможности поиска. Равенство представляет собой простейший поисковый оператор, так же как SQL-оператор LIKE .) Однако некоторые виды поиска могут быть слишком специализированными для базы данных; также поиск может быть настолько сложным, что связанные с ним SQL-операторы JOIN будут просто выполняться слишком медленно.
Иголка в миллиарде стогов сена
Многие сайты предлагают контент для определенной отрасли, рода занятий или развлечений, например, для медицины, законодательства, музыки или автотехобслуживания. Чтобы углубиться в контент такого рода, могут потребоваться специальные инструменты или знания, или просто специально организованный индекс, возвращающий релевантные и полезные результаты.
Вот несколько типичных сценариев, в которых может потребоваться собственная поисковая система:
- Найти все статьи о Кубке Стэнли, написанные Джо Хоки.
- Найти последнюю версию драйверов для многофункционального принтера HP LaserJet 3015.
- Найти запись Dinosaur Jr., показанную в «Последнем сеансе с Дэвидом Леттерманом».
Для ускорения поиска вам может потребоваться изменить структуру таблиц, чтобы упростить запросы. (Оптимизация таблиц и SQL-запросов сильно зависит от схемы и системы управления базой данных. В Интернете можно найти множество книг и статей по оптимизации производительности баз данных.) Альтернативный путь – применение специализированной поисковой системы. Какую поисковую систему применять — зависит от вида (и количества) данных, а также от вашего бюджета. Существует множество вариантов. Вы можете подключить к своей сети устройство Google, купить Endeca или другой коммерческий поисковый продукт для крупных предприятий, или попробовать Lucene. Однако во многих случаях коммерческие продукты не оправдывают рекламы или тяжелым грузом ложатся на бюджет, а Lucene, на момент написания этой статьи в июле 2007 года, не предлагал PHP API.
В качестве альтернативы можно рассмотреть Sphinx, бесплатную поисковую систему с открытым исходным кодом, предназначенную для исключительно быстрого поиска текста. Например, в реальной базе данных, состоящей примерно из 300 000 строк и пяти индексированных столбцов, где каждый столбец содержит около 15 слов, Sphinx может выдать результат по поиску «любое из этих слов» за одну сотую долю секунды (на сервере с процессором AMD Opteron с частотой 2 ГГц и 1 ГБ памяти, работающем под управлением Debian Linux® Sarge).
В Sphinx реализовано множество функций, в том числе:
- Он может индексировать любые данные, представимые в виде строк.
- Он может индексировать одни и те же данные различными способами. Создав несколько индексов, каждый из которых настроен на решение определенной задачи, вы можете выбрать наиболее подходящий для оптимизации результатов поиска.
- Он может связывать атрибуты с каждым элементом индексированных данных. Впоследствии вы можете использовать один или несколько атрибутов для фильтрации результатов поиска.
- Он поддерживает морфологические вариации слов, поэтому поиск по слову «cats» также выдаст результат по первичной словоформе «cat».
- Индекс Sphinx можно распределить по нескольким машинам, обеспечив отказоустойчивую работу.
- Он может создавать индексы префиксов слов произвольной длины и индексы инфиксов различной длины. Например, номер детали может состоять из 10 символов. Индекс префикса будет содержать все возможные подстроки, начинающиеся с начала строки. Индекс инфикса будет содержать подстроки, содержащиеся в любом месте строки.
- Sphinx можно запустить в качестве системы хранения в рамках MySQL V5, что исключает необходимость запуска еще одного демона, который зачастую рассматривается как дополнительная точка сбоя.
Полный перечень функций можно найти в Интернете и в файле README, распространяемом с исходным кодом Sphinx. На Web-сайте Sphinx также перечислено несколько проектов, в которых используется Sphinx.
Sphinx написан на C++, скомпилирован с помощью GNU, поддерживает 64-разрядные вычисления на соответствующих платформах, и работает под управлением Linux, UNIX®, Microsoft® Windows® и Mac OS X. Собрать Sphinx очень просто: Загрузите и распакуйте код, после чего запустите команду ./configure && make && make install .
По умолчанию утилиты Sphinx устанавливаются в папку /usr/local/bin/, а файл конфигурации для всех компонентов Sphinx — в папку /usr/local/etc/sphinx.conf.
Sphinx состоит из трех компонентов: генератор индекса, поисковая система и поисковая утилита, работающая в командной строке:
- Генератор индекса называется индексатором (indexer). Он выполняет запросы к базе данных, индексирует каждую колонку в каждой строке результата и привязывает каждую запись индекса к первичному ключу строки.
- Поисковая система представляет собой демон, который называется searchd. Демон получает критерии поиска и другие параметры, проходит по одному или нескольким индексам и возвращает результат. Если соответствие находится, searchd возвращает массив первичных ключей. Используя эти ключи, приложение может выполнить запрос по соответствующей базе данных и найти полные записи, удовлетворяющие критериям поиска. Searchd взаимодействует с приложением через сокет на порту 3312.
- Удобная утилита search позволяет выполнять поиск из командной строки без написания кода. Если searchd возвращает результат, поисковая система формирует запрос к базе данных и выводит строки, содержащиеся в результирующем множестве. Утилита search полезна для отладки конфигурации Sphinx и выполнения импровизированных поисковых запросов.
Кроме того, автор Sphinx Андрей Аксёнов и другие участники проекта реализовали интерфейсы для PHP, Perl, C/C++ и других языков программирования.
Поиск деталей кузова
Предположим, сайт Body-Parts.com продает детали кузовов — крылья, бамперы, хромированные детали и т.п. — для редких и коллекционных автомобилей. Как и в реальном мире, посетитель сайта Body Parts, вероятно, захочет искать детали по производителю (скажем, Porsche или производитель эквивалентных деталей), номеру изделия, марке, модели, году выпуска, состоянию (новая, восстановленная, бывшая в использовании), по описанию или по сочетанию этих характеристик.
Чтобы реализовать функцию поиска сайта Body Parts, мы будем использовать в качестве источника данных MySQL V5.0 и поисковый демон Sphinx, который будет выполнять быстрый и точный текстовый поиск. База данных MySQL V5.0 обладает очень широкими возможностями, однако функция полнотекстового поиска — не самая сильная ее черта. Фактически она ограничена таблицами MyISAM — форматом таблиц, который не поддерживает внешние ключи, и, следовательно, имеет ограниченную применимость.
В листингах с 1 по 4 показаны элементы схемы Body Parts, относящиеся к этому примеру. Вы можете увидеть таблицы Model (листинг 1), Assembly (листинг 2), Inventory (листинг 3) и Schematic (листинг 4) соответственно.
Таблица Model
Таблица Model, представленная в листинге 1, очень проста: Столбец метки указывает название модели («Corvette»); описание действует как описание автомобиля в дружественной форме («Two-door roadster; first year of introduction» — «Двухдверный родстер, первый год выпуска модели»); а begin_production и end_production обозначают, когда соответственно началось и завершилось производство этой версии. Поскольку значения упомянутых выше столбцов колонок не уникальны, каждой четверке значений столбцов (label, description, begin_production, end_production) сопоставлен отдельный идентификатор, который является внешним ключом других таблиц.
Листинг 1. Таблица Model для Body Parts
Ниже приведено несколько примеров данных для таблицы Model:
Таблица Assembly
Узел (assembly) это подсистема автомобиля, например, трансмиссия или полный набор стекол. Чтобы найти нужную запчасть, владельцы сверяются со сборочными чертежами и прилагающимися к ним спецификациями. Таблица Assembly, показанная в листинге 2, также не содержит ничего сложного: Она сопоставляет названию и описанию узла уникальный идентификатор.
Листинг 2. Таблица Assembly
Несколько примеров данных для таблицы Assembly приведены ниже:
Таблица Inventory
Таблица Inventory представляет собой канонический список деталей автомобилей. Деталь — например, болт или лампа — может присутствовать в разных автомобилях и в различных сборках, но в таблице Inventory каждая деталь упоминается только один раз. Каждая строка таблицы Inventory содержит:
- Уникальный 32-разрядный целочисленный серийный номер serialno, используемый для идентификации строки.
- Буквенно-цифровой номер детали. (Этот номер уникален и мог бы служить первичным ключом. Однако, поскольку он может содержать не только цифры, но и буквы, он не подходит для использования в Sphinx, который требует, чтобы у каждой индексируемой записи был уникальный 32-разрядный целочисленный ключ.)
- Текстовое описание.
- Цена.
Спецификация таблицы Inventory показана в листинге 3.
Листинг 3. Таблица Inventory
Фрагмент перечня деталей может выглядеть следующим образом
Таблица Schematic
Таблица Schematic связывает детали с узлами и моделями. Например, таблицу Schematic можно использовать для поиска всех деталей, составляющих двигатель кабриолета J Class 1979 года. В каждой строке таблицы Schematic содержится уникальный ID, внешний ключ к строке таблицы Inventory, внешний ключ, который идентифицирует узел, и еще один ключ, указывающий на определенную модель и модификацию из таблицы Model. Строки показаны в листинге 4.
Листинг 4. Таблица Schematic
Чтобы понять цель таблицы, посмотрите на небольшой список строк из Schematic:
Поиск по таблицам
При такой структуре таблиц можно легко ответить на множество поисковых запросов:
- Вывести все модификации определенной модели
- Показать все узлы, необходимые для сборки определенной модели и модификации
- Показать все детали, входящие в конкретный узел определенной модели и модификации
Однако некоторые типы запросов будут особенно затратны по времени:
- Найти все вхождения деталей в любой модели и модификации, номера которых начинаются с «WIN»
- Найти детали, в описании которых указано «lacquer» (покрыто лаком) или «paint» (окрашено)
- Найти все детали, в описании которых указано «black leather» (черная кожа)
- Найти все детали J Series 2002 года со словом «paint» (окрашено) в описании
Чтобы выполнить поиск такого вида, нужно делать громоздкие запросы с множеством JOIN или с ресурсоемкими операторами LIKE , особенно в случаях, когда таблицы Inventory и Schematic очень большие. Более того, сложный текстовый поиск вообще лежит за пределами возможностей MySQL. Если нужен поиск в больших объемах текстовых данных, стоит подумать о создании и использовании индекса Sphinx.
Интеграция программного обеспечения Sphinx
Чтобы решить проблему с помощью Sphinx, нужно определить один или несколько источников данных и один или несколько индексов.
Источник (source) определяет базу данных, которую нужно индексировать, предоставляет информацию для аутентификации и указывает запросы, которые нужно использовать для формирования каждой из строк. При желании источник может определять один или несколько столбцов как фильтры, или, как это называется в Sphinx, группы (group). Группы используются для фильтрации результатов. Например, по слову «paint» может выдаваться 900 совпадений. Если вас интересуют совпадения только для определенной модели, вы можете отфильтровать результат по группе model.
Для индекса (index) необходимо, чтобы был определен источник (то есть множество строк) и способ классификации данных, извлеченных из этого источника.
Источник(и) и индекс(ы) определяются в файле sphinx.conf. Источником для сайта Body Parts является база данных MySQL. В листинге 5 показана часть определения источника под названием catalog — фрагмент показывает, к какой базе данных подключаться и как выполнять соединение (сервер, сокет, пользователь и пароль).
Листинг 5. Настройки доступа к базе данных MySQL
Теперь необходимо создать запрос, который будет возвращать строки, подлежащие индексации. Обычно, чтобы получить строку, вы создаете запрос SELECT , возможно, соединяя множество таблиц с помощью JOIN . Здесь, однако, имеется проблема: Для поиска модели и года выпуска необходимо использовать таблицу Assembly, а номер детали и ее описание можно найти только в таблице Inventory. Для выполнения своих функций Sphinx необходима возможность связать результат с 32-разрядным целочисленным первичным ключом.
Для получения данных в нужной форме создадим представление (view)— — новую конструкцию, реализованную в MySQL V5, которая собирает колонки из различных таблиц в единую сборную виртуальную таблицу. При работе с представлениями все данные, необходимые для любого вида поиска, находятся в одном месте, даже в том случае, если фактические данные располагаются в других таблицах. В листинге 6 показан SQL-запрос, определяющий представление Catalog.
Листинг 6. Представление Catalog собирает данные в виртуальную таблицу
Если вы создали базу данных body_parts с показанными ранее таблицами и данными, представление Catalog будет иметь примерно следующий вид:
Поле id представления указывает на запись детали в таблице Inventory. Столбцы partno и description содержат собственно текст для поиска, а столбцы assembly и model служат группами для дальнейшей фильтрации результатов. При наличии такого представления поисковые запросы создаются моментально. В листинге 7 показана оставшаяся часть определения источника данных catalog.
Листинг 7. Запрос на создание строк для индексации
В запрос sql_query должен входить первичный ключ, который вы хотите использовать в последующем для поиска, а также все поля, которые вы желаете индексировать и использовать в качестве групп. Две записи sql_group_column объявляют, что для фильтрации результатов могут использоваться поля Assembly и Model. Для поиска нужных записей в поисковой утилите используется sql_query_info . В запросе $id заменяется каждым первичным ключом, возвращенным searchd.
Последним действием по настройке является построение индекса. В листинге 8 показан индекс для источника данных catalog.
Листинг 8. Описание одного из возможных индексов для источника catalog
В строке 1 дается ссылка на именованный источник данных в файле sphinx.conf. Во второй строке определяется, где хранить индексированные данные; по умолчанию индексы Sphinx хранятся в /var/data/sphinx. В строке 3 указывается на необходимость использования английского морфологического словаря. Строки 5-7 говорят индексатору о том, что необходимо индексировать только слова, состоящие из трех символов и более, и включать в индекс инфиксов все подстроки, содержащие три символов и более. (Для простоты в листинге 9 показан весь файл sphinx.conf для сайта Body Parts.)
Листинг 9. Пример sphinx.conf для Body Parts
В расположенном в конце файла разделе searchd выполняется настройка демона searchd. Записи этого раздела говорят сами за себя. Особенно полезен параметр query.log (журнал запросов): В него заносятся все запущенные поисковые запросы, а также результаты их выполнения, например, количество документов, по которым производился поиск, и количество совпадений.
Создание и проверка индекса
Теперь мы готовы сформировать индекс для приложения Body Parts. Для этого:
- Создадим иерархию каталогов /var/data/sphinx, выполнив: $ sudo mkdir -p /var/data/sphinx
- Предполагая, что MySQL работает, запустите индексатор, выполнив приведенный ниже код.
Листинг 10. Создание индексов
Листинг 11. Проверка индекса с помощью search
Первая команда, /usr/local/bin/search —config /usr/local/etc/sphinx.conf ENG , находит два упоминания ENG в номерах деталей. Вторая команда, /usr/local/bin/search —config /usr/local/etc/sphinx.conf wind , находит подстроку wind в двух описаниях деталей. А третья команда ограничивает результат только теми записями, в которых model равно 3 .
Написание кода
Теперь, наконец, вы можете приступать к написанию кода PHP для вызова поисковой системы Sphinx. API-интерфейс Sphinx для PHP невелик и очень прост в освоении. В листинге 12 показано небольшое приложение PHP, которое вызывает searchd и извлекает те же результаты, что и последняя команда, показанная выше («найти все детали, в названии которых есть слово ‘cylinder’, принадлежащие модели 3»).
Листинг 12. Вызов поисковой системы из PHP
Для проверки кода создайте директорию log для Sphinx, запустите searchd, после чего запустите приложение PHP, как показано ниже.
Листинг 13. Приложение PHP
Результатом будет 9: правильный первичный ключ единственной строки, удовлетворяющей запросу. Если Sphinx находит совпадение, в ассоциативный массив $result записывается элемент results . Посмотрите на результат работы print_r() и посмотрите, что ещё выводится.
Одно замечание: total_found это общее количество совпадений, найденных в индексе, а found это количество выведенных результатов. Эти две величины могут различаться, поскольку вы можете изменять число результатов, выводимых при каждом запуске, а также то, какие результаты возвращать, что удобно для постраничного вывода длинных списков результатов. Обратите внимание на вызов API SetLimits() . Одним из способов организации постраничного вывода является вызов поисковой системы со следующими параметрами: $cl->SetLimits( ( $page — 1 ) * SPAN, SPAN ) для выдачи первой, второй, третьей (и т.д.) группы результатов SPAN , в зависимости от того, какую страницу вы хотите вывести.
Исследуйте тайны Сфинкса
В Sphinx реализовано множество полезных функций. В этой статье я обрисовал только самые общие моменты, но теперь у вас есть реальный работающий пример, с которого можно начать дальнейшее изучение.
Внимательно ознакомьтесь с примером файла конфигурации Sphinx, /usr/local/etc/sphinx.conf.dist, который входит в комплект поставки. Комментарии, приведенные в этом файле, объясняют, что делает тот или иной параметр Sphinx; показывают, как создать распределенную конфигурацию с резервированием; а также объясняют, как наследовать параметры базы данных, чтобы избежать повторения в источниках и индексах. Файл README Sphinx также является великолепным источником информации, в том числе о том, как встраивать Sphinx непосредственно в MySQL V5 — без демонов.
В следующий раз мы попробуем найти лучшее решение для отладки кода PHP, чем echo() и print_r() .
Ресурсы для скачивания
Похожие темы
- Оригинал статьи Build a custom search engine with PHP (EN).
- Sphinx (EN) это бесплатная поисковая система с открытым исходным кодом, предназначенная для выполнения исключительно быстрого текстового поиска.
- Познакомьтесь с Endeca и другими крупными коммерческими поисковыми продуктами, или попробуйте Lucene.(EN)
- PHP.net является центральным ресурсом для PHP-разработчиков.(EN)
- Познакомьтесь с «Рекомендованным списком литературы по PHP (EN).»
- Расширьте ваши навыки в PHP, ознакомившись с ресурсами проекта PHP IBM developerWorks.(EN)
- Прослушать интересные интервью и беседы разработчиков программного обеспечения можно в подкастах developerWorks.(EN)
- Работаете с базами данных на PHP? Познакомьтесь с Zend Core for IBM, готовой, прозрачной и простой в установке среде разработки и внедрения PHP, которая поддерживает IBM DB2 V9.(EN)
- Ищете базу данных для работы с вашим приложением PHP? Загрузите IBM DB2 Express-C 9, бесплатную версию сервера данных DB2 Express V9.(EN)
- Посетите Раздел Open Source сайта developerWorks и найдите множество инструкций, инструментов, а также новостей проектов, которые помогут вам разрабатывать приложения с открытым исходным кодом и использовать их вместе с продуктами IBM.
- Дополните ваш следующий проект разработки программного обеспечения с открытым исходным кодом ознакомительными версиями программного обеспечения IBM, которые можно скачать из Интернета или заказать на DVD.(EN)
- Загрузите ознакомительные версии продуктов IBM и поработайте с инструментами для разработки приложений и системным программным обеспечением DB2®, Lotus®, Rational®, Tivoli® и WebSphere®.(EN)
Комментарии
Войдите или зарегистрируйтесь для того чтобы оставлять комментарии или подписаться на них.
Источник статьи: http://www.ibm.com/developerworks/ru/library/os-php-sphinxsearch/