- PVSM.RU - https://www.pvsm.ru -
В какой-то момент разработки проекта встал вопрос поиска по большому количеству текстов. Причем, тексты имеют различную длину: от твиттов до больших статей. Сначала, основным поисковым движком был выбран встроенный в Postgres _tsvector. Для поиска по простым правилам его было вполне достаточно. Массив текстов рос с большой скоростью, а правила поиска усложнялись, поэтому встроенный движок уже не покрывал требований.
Да, существует sphinx, у него есть отличная интеграция с Postgres, но была цель найти решение для использования elasticsearch с Postgres. Почему? elasticsearch показывал хорошие результаты в некоторых case-ах проекта. Да и уже был сервер с ним для хранения логов logstash-а. Также было желание найти такой инструмент, который полностью возьмет на себя синхронизацию данных.
В результате всего на просторах сети был найден проект ZomboDb, который как раз подходил под требования.
Страница проекта на github [1].
Этот раздел является пересказом официальной инструкции.
Поддерживаемые на данный момент версии пакетов:
Пакет | Версии |
---|---|
Elasticsearch | 1.7.1+ (not 2.0) |
Postgres | 9.3, 9.4, 9.5 |
Моя конфигурация: Postgres 9.4, elasticsearch 1.7.5
В postgresql.conf добавить строку:
local_preload_libraries = 'zombodb.so'`
Перезапустить базу и создать extension:
psql db_name -c "CREATE EXTENSION zombodb;"
Далее, с той-же страницы необходимо скачать плагин для elasticsearch и установить его:
bin/plugin -i zombodb -u file:///path/to/zombodb-plugin-X.X.X.zip
Добавить в elasticsearch.yml:
threadpool.bulk.queue_size: 1024
threadpool.bulk.size: 12
http.max_content_length: 1024mb
index.query.bool.max_clause_count: 1000000
На этом установка закончена
Предположим, есть таблицы, в которой лежат теги:
CREATE TABLE public.tags (
id INTEGER PRIMARY KEY NOT NULL DEFAULT nextval('tags_id_seq'::regclass),
word CHARACTER VARYING(100) NOT NULL
);
Создание индекса:
CREATE INDEX tags_zdb_search_idx
ON tags
USING zombodb (zdb('tags', tags.ctid), zdb(tags))
WITH (url='http://localhost:9200/');
В результате этого запроса создается индекс, и данные сразу поступают в elasticsearch.
Запрос, который найдет слова мама и папа:
SELECT *
FROM tags
WHERE zdb('tags', ctid) ==> 'word:(мама,папа)';
Где word — название поля, по которому будет производиться поиск. Поиск реализуется с помощью оператора ==>.
Также, ZomboDb предоставляет домены phrase и fulltext, базирующиеся на типе text. Используя собственные домены можно определять маппинг для elasticsearch.
С помощью запросов можно искать по отдельным полям индексируемой таблицы, также и по всем полям.
Запросы поддерживают логические операции (and, or, not), скобки.
Есть возможность использовать различные поисковые операторы. Например, запрос
SELECT *
FROM texts
WHERE zdb('texts', ctid) ==> 'text:папа';
где оператором является двоеточие, вернет тексты, содержащие слово папа.
Также поддерживаются операции more like this и fuzzy like this через операторы :@ и :@~ соответственно.
Пример:
SELECT *
FROM texts
WHERE zdb('texts', ctid) ==> '(text:@папа and title:@мама) or text:тетя';
Также, есть поддержка операторов сравнения:
SELECT *
FROM texts
WHERE zdb('texts', ctid) ==> 'comments > 10';
Подробное описание языка запросов в документации [3].
Проект является хорошим продуктом, который работает "из коробки". Хорошо документирован, обновляется (поддерживается последняя версия Postgres, последний коммит на момент написания статьи 27-и дневной давности). Если хорошо и стабильно покажет себя в production, напишу обертку для sqlalchemy.
Спасибо за внимание!
Автор: vpiskunov
Источник [4]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/postgresql/139524
Ссылки в тексте:
[1] github: https://github.com/zombodb/zombodb
[2] страницы: https://github.com/zombodb/zombodb/releases/tag/v3.0.0
[3] документации: https://github.com/zombodb/zombodb/blob/master/SYNTAX.md
[4] Источник: https://habrahabr.ru/post/303744/?utm_source=habrahabr&utm_medium=rss&utm_campaign=sandbox
Нажмите здесь для печати.