Обновления дельта-индекса sphinxsearch

У меня проблема с обновлениями Delta-index.
Если идентификатор документа меньше, чем max_doc_id, не включен в дельта-индекс, поэтому до тех пор, пока main-index не будет обновлен, изменения не будут применять эти данные.
Предположим, у нас есть 1000 данных.
Если пятидесятый документ будет изменен, в дельта-индексе изменений не будет.
Как в дельта-индекс включаются изменения документов, когда их идентификатор меньше max_doc_id?
Есть ли способ, чтобы дельта-индекс включал данные, которые обновляются, чтобы нам не приходилось ждать запуска основного индекса?

CREATE TABLE sph_counter
(
    counter_id INTEGER PRIMARY KEY NOT NULL,
    max_doc_id INTEGER NOT NULL
);
source main
{
    # ...
    sql_query_pre = SET NAMES utf8
    sql_query_pre = REPLACE INTO sph_counter SELECT 1, MAX(id) FROM documents
    sql_query = SELECT id, title, body FROM documents \
     WHERE id<=( SELECT max_doc_id FROM sph_counter WHERE counter_id=1 )
}

source delta : main
{
    sql_query_pre = SET NAMES utf8
    sql_query = SELECT id, title, body FROM documents \
     WHERE id>( SELECT max_doc_id FROM sph_counter WHERE counter_id=1 )
}

2 ответа

Очень простой способ, который мне нравится для этого, это просто добавить столбец отметки времени для автоматического отслеживания измененных документов.

Добавить столбец...

ALTER TABLE documents 
   ADD updated TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
   INDEX(updated);

Значение по умолчанию также важно, поэтому в него также включены вновь созданные документы.

Тогда можете просто использовать это в запросах со списком уничтожений. Основное будет включать в себя все документы на момент индексации. Но дельта будет включать в себя новые и измененные документы. Список уничтожений означает, что старая версия в main игнорируется.

CREATE TABLE sph_counter
(
    counter_id INTEGER PRIMARY KEY NOT NULL,
    max_doc_id INTEGER NOT NULL,
    indexing_time DATETIME NOT NULL
);
source main
{
    # ...
    sql_query_pre = SET NAMES utf8
    sql_query_pre = REPLACE INTO sph_counter SELECT 1, MAX(id), NOW() FROM documents
    sql_query = SELECT id, title, body FROM documents
}

source delta : main
{
    sql_query_pre = SET NAMES utf8

    sql_query = SELECT id, title, body FROM documents \
     WHERE updated > ( SELECT indexing_time FROM sph_counter WHERE counter_id=1 )

    sql_query_killlist = SELECT id FROM documents \
     WHERE updated > ( SELECT indexing_time FROM sph_counter WHERE counter_id=1 )
}

(Как и список уничтожений, нет смысла фильтровать основную часть, дубликаты не имеют значения. Также не нужно max_doc_id - так что sph_counter можно упростить вместе с sql_query_pre. Во многих случаях стыдно повторять запрос в списке уничтожений. Не могу просто сказать sphinx использовать все документы в индексе в качестве списка уничтожения)

Если вы хотите отслеживать обновления документа вместе со вставками, у вас должен быть отдельный столбец для редакции документа. Значения ревизий должны быть уникальными для всей таблицы документов, поэтому для их генерации рекомендуется использовать глобальную последовательность.

Когда вы обновляете существующий документ или вставляете новый, вы должны взять следующее значение из последовательности ревизий и сохранить его в столбце ревизии документа. Иногда полезно иметь триггеры БД для автоматического обновления версий.

Затем в sql_query_pre раздел вы можете сохранить минимальные и максимальные значения ревизии в sph_counter таблица и использовать их для создания правильного дельта-индекса.

Другие вопросы по тегам