В этой статье мы обсудим, как работают списки исключений в Manticore Search 3.
Обычные индексы неизменяемы в плане добавления новых документов: после создания невозможно добавить больше данных, можно только обновить атрибуты существующих документов. Чтобы поддерживать индекс в соответствии с основными данными (которые могут быть базой данных или файлами), индекс необходимо обновить, выполнив полную перестройку. Эта операция может занять время. В некоторых случаях полная перестройка может занять часы или даже больше.
Это означает, что данные, доступные для поиска, могут отставать от оригинального хранилища данных, и последний контент имеет время ожидания до тех пор, пока индекс не будет перестроен. Чтобы исправить это, была введена концепция дельта-индекса. Дельта — это индекс с такой же структурой, как и больший (так называемый 'основной') индекс, но он предназначен для захвата документов, которые были добавлены в базу данных после создания основного индекса. Точка захвата обычно является идентификатором документа или временной меткой.
В то время как дельта захватывает новые документы (которые никогда не существовали), в большинстве случаев также желательно захватывать измененные документы. Еще одним распространенным требованием является возможность каким-то образом отбрасывать документы, которые были удалены. Измененные документы могут быть включены в дельту, но они создают проблему: поиск как в основном, так и в дельта-индексах приведет к двум версиям одного и того же документа — старой в основном и новой в дельте — и движок не знает, какую из них выбрать.
Чтобы преодолеть эти проблемы, была добавлена новая концепция: список исключений — это список идентификаторов документов в дельта-индексе, которые известны как измененные или удаленные, чтобы индекс игнорировал их при поиске в основном индексе.
Пока все хорошо. Однако в v2 движок должен был применять список исключений к набору результатов, извлеченному из основного индекса, перед объединением с набором результатов из дельты, чтобы предоставить окончательный результат. Хотя в целом это работало хорошо для многих пользователей, применение списков исключений к каждому запросу действительно влияет на производительность. Это не заметно на маленьких индексах или маленьких списках исключений, но начинает сказываться на больших индексах, которые "занимают вечность" для перестройки, для которых дельта-индексы могут в конечном итоге иметь большие наборы списков исключений.
<img src="killlists-v2-optimized.webp" alt="img"> Списки исключений в 2.x
Manticore 3 ввел разрушающее изменение, проведя масштабное обновление движка хранения индексов. Списки исключений также нуждались в изменении.
Это было вызвано двумя причинами: существующий способ списков исключений оказался проблематичным в некоторых крайних случаях, и он также не подходил для нового движка хранения.
Поэтому вместо того, чтобы применять списки исключений каждый раз, когда выполняется запрос, почему бы не сделать это один раз? В v3 в источниках дельта-индекса мы все еще определяем источник для списков исключений (sql_query_killlist), но в конфигурации индекса нам нужно определить цели списков исключений.
Когда индексы загружаются, движок проверяет, есть ли для индекса список исключений, который необходимо применить. Если один (или несколько) найден, он применяет этот список исключений к индексу, помечая соответствующие документы как удаленные. Когда выполняется запрос по индексу, эти помеченные документы просто игнорируются (как будто их не существует). Поскольку это подавление уже выполнено при запуске или ротации индекса, наличие дельты не требуется для того, чтобы удаленные документы больше не отображались в результатах.
<img src="killlists-v3-optimized.webp" alt="img"> Цели списков исключений определяются в директиве killlist_target . Директива ожидает список индексов и режим примененных списков исключений. В настоящее время поддерживаются 3 режима:
kl - идентификаторы документов из определенного списка исключений (по sql_query_killlist) будут использоваться для подавления
id - вместо этого используются идентификаторы документов из индекса (и любой определенный sql_query_killlist будет игнорироваться)
или по умолчанию, если вы не укажете 'kl' или 'id', будут использоваться как идентификаторы документов из индекса, так и sql_query_killlist
Пример
index delta {
...
killlist_target = index_one:kl, index_two:id
...
}
Директиву цели можно изменить с помощью команды ALTER TABLE, но для применения целевые индексы должны быть перезагружены. Также ALTER не может "отключить" уже удаленные идентификаторы в целевом индексе (убрав индекс из списка целей).
Новый способ работы списков исключений улучшает производительность запросов, так как теперь во время запроса нет дополнительных операций для сравнения найденных идентификаторов документов с списком подавления. Более того, постоянная маркировка подавленных идентификаторов документов означает более короткий список идентификаторов, который необходимо искать при каждом запросе. Это также добавляет гибкость, так как для подавления могут использоваться не только идентификаторы из специального списка (сгенерированного sql_killlist_query), но и идентификаторы документов всего индекса, если это необходимо.