Пошук по Postgres з використанням ZomboDb і elasticsearch

В якийсь момент розробки проекту постало питання пошуку за великою кількістю текстів. Причому, тексти мають різну довжину: від твітів до великих статей. Спочатку, основним пошуковим движком був обраний вбудований в Postgres _tsvector. Для пошуку по простих правилах його було цілком достатньо. Масив текстів зростав з великою швидкістю, а правила пошуку ускладнювалися, тому вбудований движок вже не покривав вимог.
Так, існує sphinx, у нього є відмінна інтеграція з Postgres, але була мета знайти рішення для використання elasticsearch з Postgres. Чому? elasticsearch показував хороші результати в деяких case-ах проекту. Та й вже був сервер з ним для зберігання логів logstash-а. Також було бажання знайти такий інструмент, який повністю візьме на себе синхронізацію даних.
В результаті на просторах мережі був знайдений проект ZomboDb, який якраз підходив під вимоги.
Сторінка проекту на github.
Установка розширення
Цей розділ є переказом офіційній інструкції.
Підтримуються на даний момент версії пакетів:





Пакет Версії Elasticsearch 1.7.1+ (not 2.0) Postgres 9.3, 9.4, 9.5
Моя конфігурація: Postgres 9.4, elasticsearch 1.7.5
  1. сторінки необхідно скачати і встановити пакет з плагіном для Postgres (deb або rpm)
  2. postgresql.conf додати рядок:
    local_preload_libraries = 'zombodb.so"

  3. Перезавантажити базу і створити extension:
    psql db_name -c "CREATE EXTENSION zombodb;"

  4. Далі, з тієї ж сторінки необхідно завантажити плагін для elasticsearch і встановити його:
    bin/plugin -i zombodb -u file:///path/to/zombodb-plugin-X.X.X.zip

  5. Додати elasticsearch.yml:
    threadpool.bulk.queue_size: 1024
    threadpool.bulk.size: 12
    http.max_content_length: 1024mb
    index.query.bool.max_clause_count: 1000000

  6. Перезапустити elasticsearch.
На цьому установка закінчена
Створення тестового індексу
Припустимо, є таблиці, в якій лежать теги:
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 *
Tags FROM
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';

Докладний опис мови запитів документації.
Висновки
Проект є хорошим продуктом, який працює "з коробки". Добре документований, оновлюється (підтримується остання версія Postgres, останній комміт на момент написання статті 27-денної давності). Якщо добре і стабільно покаже себе у production, напишу обгортку для sqlalchemy.
Дякую за увагу!
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.