Arhn - архитектура программирования

Советы по поиску крупного текста в Postgres

Я новичок в базах данных, и мне нужен совет высокого уровня.

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

CREATE TABLE errorlogs (
     id SERIAL PRIMARY KEY,
     archive_id INTEGER NOT NULL REFERENCES archives,
     filename VARCHAR(256) NOT NULL,
     content TEXT);

Текст в содержании может варьироваться по длине от 1k до 50MB.

Проблема
Я хотел бы иметь возможность выполнять достаточно быстрый текстовый поиск данных в столбце "content" (например, WHERE CONTENT LIKE '%some_error%'). Прямо сейчас поиск очень медленный (> 10 минут для поиска по 8206 строкам).

Я знаю, что индексирование предназначено для решения моей проблемы, но я, кажется, не могу создавать индексы - всякий раз, когда я пытаюсь, я получаю сообщения об ошибках, что индекс будет слишком большим.

=# CREATE INDEX error_logs_content_idx ON errorlogs (content text_pattern_ops);
ОШИБКА: строка индекса требует 1796232 байт, максимальный размер 8191

Я надеялся на некоторые советы о том, как обойти эту проблему. Могу ли я изменить максимальный размер индекса? Или мне не стоит пытаться использовать Postgres для полнотекстового поиска в таких больших текстовых полях?

Любой совет очень ценится!

15.01.2015

  • Я думаю, вы, вероятно, ищете полнотекстовый поиск/индексацию postgresql.org /docs/9.1/static/textsearch-intro.html. 15.01.2015
  • Этот ответ также может помочь, stackoverflow.com /вопросы/1566717/ 15.01.2015
  • Привет Джон, спасибо за совет. Я уже просмотрел документы текстового поиска и не смог найти никакой информации об ограничениях индекса. Второй опубликованный вами комментарий описывает создание индекса text_pattern_ops, который, как я уже упоминал выше, возвращает ошибку о том, что индекс слишком велик. 15.01.2015
  • Вы хотите использовать индекс gin или gist, а не B-дерево, над которым работает text_pattern_ops. Извиняюсь за плохую ссылку. 15.01.2015
  • Я тоже пробовал это, я получаю аналогичные ошибки о том, что данные слишком велики для tsvector, используя что-то вроде: WHERE to_tsvector(content) @@ to_tsquery('Stacktrace') (без индекса) 15.01.2015
  • Я получаю УВЕДОМЛЕНИЯ, а не ОШИБКИ, при использовании to_tsvector для строк, содержащих очень большие слова. Хотя, если ваш контент содержит слова длиной более 2047 символов, я должен задаться вопросом, не являются ли они на самом деле двоичными данными, что может означать, что он может иметь символы \0, что вызовет проблемы. 16.01.2015
  • Данные, которые я индексирую, определенно не являются двоичными. Это очень большие файлы журналов, и есть вероятность, что слово может иметь длину более 2047 символов. У вас случайно нет ссылки на информацию об этих ограничениях? Было бы очень полезно... 16.01.2015
  • Я не знаю, что предел 2047 где-либо задокументирован. Я просто эмпирически исхожу из того, что вижу с select to_tsvector('simple',(select string_agg(md5(x::text),'') from generate_series(1,1000) x(x))||' Stacktrace' ); 17.01.2015

Ответы:


1

Векторы текстового поиска не могут обрабатывать такие большие данные — см. задокументированные ограничения< /а>. Их сила заключается в нечетком поиске, поэтому вы можете искать «плавать» и находить «плавать», «плавать», «плавать» и «плавать» в одном и том же вызове. Они не предназначены для замены grep.

Причина ограничений указана в исходном коде как MAXSTRLEN (и MAXSTRPOS). Векторы текстового поиска хранятся в одном длинном непрерывном массиве длиной до 1 МБ (сумма всех символов для всех уникальных лексем). Чтобы получить к ним доступ, структура индекса ts_vector позволяет использовать 11 бит для длины слова и 20 бит для его позиции в массиве. Эти ограничения позволяют структуре индекса вписаться в 32-битное целое число без знака.

Вы, вероятно, сталкиваетесь с одним или обоими из этих ограничений, если у вас слишком много уникальных слов в файле ИЛИ слова повторяются очень часто - что вполне возможно, если у вас есть файл журнала размером 50 МБ с квазислучайными данными.

Вы уверены, что вам нужно хранить файлы журналов в базе данных? Вы в основном копируете файловую систему, и grep или python могут довольно хорошо выполнять поиск. Однако, если вам действительно нужно, вы можете подумать об этом:

CREATE TABLE errorlogs (
    id SERIAL PRIMARY KEY
    , archive_id INTEGER NOT NULL REFERENCES archives
    , filename VARCHAR(256) NOT NULL
);

CREATE TABLE log_lines (
    line PRIMARY KEY
    , errorlog INTEGER REFERENCES errorlogs(id)
    , context TEXT
    , tsv TSVECTOR
);

CREATE INDEX log_lines_tsv_idx ON log_lines USING gin( line_tsv );

Здесь вы рассматриваете каждую строку журнала как "документ". Для поиска вы должны сделать что-то вроде

SELECT e.id, e.filename, g.line, g.context
FROM errorlogs e JOIN log_lines g ON e.id = g.errorlog 
WHERE g.tsv @@ to_tsquery('some & error');
24.04.2015
  • Большое спасибо за предложение. С тех пор я переключился на хранение одной строки журнала в строке. Я еще не пробовал индексировать - только что попробовал, и все работает хорошо. Спасибо еще раз! 26.04.2015
  • Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..