Задача поиска по тексту предполагает работу со сложными индексами и большими объемами данных. Поэтому для ее решения образовалась целая группа отдельных инструментов.
Многие базы данных имеют встроенную возможность поиска по тексту, однако всегда это очень ограниченная реализация. В большинстве случаев следует использовать более подходящие технологии.
Все технологии полнотекстового поиска работают по одному принципу. На основе текстовых данных строится индекс, который способен очень быстро искать соответствия по ключевым словам.
Обычно сервис поиска состоит из двух компонент. Поисковик и индексатор.
Индексатор получает текст на вход, делает обработку текста (вырезание окончаний, незначимых слов и т.п.) и сохраняет все в индексе. Устройство такого индекса позволяет проводить по нему очень быстрый поиск.
Поисковик — интерфейс поиска по индексу — принимает от клиента запрос, обрабатывает фразу и ищет ее в индексе.
Существует несколько популярных технологий для реализации полнотекстового поиска в приложениях.
Супер простое решение, которое подойдет для большинства случаев. По умолчанию поддерживает английский и русский язык. Имеет интерфейс для индексирования таблиц MySQL. Чтобы начать использовать Sphinx достаточно установить его из пакетов, настроить источник данных и запустить индексатор в cron задачу.
Конфигурация делится на source и index для определения источника данных и параметров индекса:
source product_product { type = mysql sql_host = 127.0.0.1 sql_user = root sql_pass = root sql_db = shop sql_query = SELECT id, title, description FROM products } index product { source = product path = /var/data/product charset_type = utf-8 }
# настройка индексации таблицы products прямо из базы MySQL
После этого достаточно запустить индексатор в cron, например для переиндексации каждые 5 минут:
*/5 * * * * root [ -x /usr/bin/indexer ] && /usr/bin/indexer --quiet --rotate --all
В таком режиме максимальная задержка до появления данных в поиске будет составлять 5 минут.
Sphinx поддерживает обычный MySQL протокол для поиска, поэтому чтобы найти в индексе какой-то текст достаточно подключиться к порту 9306 и отправить обычный MySQL запрос:
SELECT id FROM products WHERE MATCH("htc one x")
# В результате будут возвращены id найденных документов
Например, в PHP:
<? $sp = new PDO('mysql:host=127.0.0.1;port=9306', 'root', ''); $list = $sp->query('SELECT id FROM products WHERE MATCH("htc one x")'); while ( $row = $list->fetch(PDO::FETCH_ASSOC) ) { $product = get_product_by_id($row['id']); # достаем данные из MySQL echo $product['title'] . '<br/>'; }
# Sphinx вернет ID, по которому можно получить данные продукта из MySQL
При больших объемах можно использовать схему Delta индексов для ускорения индексации. Кроме этого, Sphinx поддерживает Real Time индексы, фильтрацию и сортировку результатов поиска и поиск по wildcard условиям.
Solr – не просто поисковый индекс, а еще и хранилище документов. Т.е. в отличие от Sphinx’a, документы сохраняются целиком и их не нужно дублировать в базу данных.
Решение Java-based, поэтому понадобится JVM и сам Solr. Из пакетов можно поставить все вместе:
apt-get install solr-jetty
Либо просто скачать Solr и запустить его:
wget http://apache.cp.if.ua/lucene/solr/5.3.1/solr-5.3.1.tgz tar -xvf solr-5.3.1.tgz cd solr-5.3.1 bin/solr start
После этого сервис станет доступен на порту 8983:
http://127.0.0.1:8983/
Solr работает по текстовому HTTP протоколу. Сразу после установки можно отправлять данные в индекс. Индекс — это что-то вроде таблицы в MySQL, для ее создания нужно выполнить команду:
bin/solr create -c shop
# создаем индекс shop
Чтобы добавить документ в индекс, достаточно отправить такой запрос.
curl http://localhost:8983/solr/shop/update -d ' [ {"id" : "1", "title_t" : "The Solr And Shit", "author_t" : "Den Golotyuk" } ]'
# Приставка _t нужна, чтобы значение стало доступно для полнотекстового поиска
Теперь можно сделать выборку документа по ID:
curl http://localhost:8983/solr/shop/get?id=1
Чтобы стала доступной возможность поиска по индексу, необходимо запустить перестроение индекса:
curl http://localhost:8983/solr/shop/update?commit=true
После этого можно искать по тексту:
curl http://localhost:8983/solr/demo/query -d 'q=author_t:Den'
Получим что-то типа этого:
{ "responseHeader":{ "status":0, "QTime":13, "params":{ "q":"author_t:Den" } }, "response":{ "numFound":1, "start":0, "docs":[ { "id":"4", "title_t":[ "Sphinx And Solr" ], "author_t":[ "Den Golotyuk" ], "_version_":1513752384077037568 } ] } }
Solr поддерживает масштабирование в кластер, поэтому это решение подойдет для очень больших объемов данных и нагрузок. Кроме обычного текстового поиска этот поисковик может находить неточные соответствия (например, при поиске слов с ошибками).
Elastic]search — целая инфраструктура для работы с данными, в том числе полнотекстовым поиском. Построен на основе Apache Lucene.
Установка из кастомного репозитория Debian:
wget -qO - https://packages.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add - echo "deb http://packages.elastic.co/elasticsearch/1.4/debian stable main" | sudo tee -a /etc/apt/sources.list apt-get update && apt-get install elasticsearch update-rc.d elasticsearch defaults 95 10 /etc/init.d/elasticsearch restart
После запуска (может занять несколько секунд) нужно проверить доступность:
curl localhost:9200
{ "status":200, "name":"Hermod", "cluster_name":"elasticsearch", "version":{ "number":"1.6.2", "build_hash":"622039121e53e5f520b5ff8720fdbd3d0cb5326b", "build_timestamp":"2015-07-29T09:24:47Z", "build_snapshot":false, "lucene_version":"4.10.4" }, "tagline":"You Know, for Search" }
Индексы (таблицы) создаются автоматически при индексации, а сам индексатор работает в режиме реального времени. Поэтому для добавления документа в индекс нужно сделать только один вызов:
curl -XPUT "http://localhost:9200/shop/products/1" -d' { "title": "Elastic", "description": "Better than Solr" }'
# сохраняем продукт в индекс shop/products с id = 1
{"_index":"shop","_type":"products","_id":"1","_version":1,"created":true}
Чтобы получить документ по id достаточно сделать такой вызов:
curl -XGET "http://localhost:9200/shop/products/1"
Для поиска документов по тексту:
curl -XPOST "http://localhost:9200/shop/products/_search" -d' { "query": { "query_string": { "query": "Better" } } }'
{ "took":1395, "timed_out":false, "_shards":{ "total":5, "successful":5, "failed":0 }, "hits":{ "total":1, "max_score":0.15342641, "hits":[ { "_index":"shop", "_type":"products", "_id":"1", "_score":0.15342641, "_source":{ "title":"Elastic", "description":"Better than Solr" } } ] } }
Elastic имеет мега продвинутую систему хранения данных и протокол запросов. Поэтому во многих случаях его применяют, как движок для Ad-hoc запросов.
Для поиска по тексту следует использовать указанные инструменты, т.к. обычные базы данных весьма ограничены и неэффективны в этом вопросе. Короткая сводка поможет выбрать подходящее решение:
Прокси (proxy), или прокси-сервер — это программа-посредник, которая обеспечивает соединение между пользователем и интернет-ресурсом. Принцип…
Согласитесь, было бы неплохо соединить в одно сайт и приложение для смартфона. Если вы еще…
Повсеместное распространение смартфонов привело к огромному спросу на мобильные игры и приложения. Миллиарды пользователей гаджетов…
В перечне популярных чат-ботов с искусственным интеллектом Google Bard (Gemini) еще не пользуется такой популярностью…
Скрипт (англ. — сценарий), — это небольшая программа, как правило, для веб-интерфейса, выполняющая определенную задачу.…
Дедлайн (от англ. deadline — «крайний срок») — это конечная дата стачи проекта или задачи…