<!DOCTYPE article PUBLIC "-//NLM//DTD JATS (Z39.96) Journal Archiving and Interchange DTD v1.0 20120330//EN" "JATS-archivearticle1.dtd">
<article xmlns:xlink="http://www.w3.org/1999/xlink">
  <front>
    <journal-meta />
    <article-meta>
      <title-group>
        <article-title>О структуре легко обновляемых полнотекстовых индексов</article-title>
      </title-group>
      <contrib-group>
        <aff id="aff0">
          <label>0</label>
          <institution>Copyright c by the paper's authors. Copying permitted for private and academic purposes. In: A.A. Makhnev, S.F. Pravdin (eds.): Proceedings of the International Youth School-conference 3⁄4SoProMat-2017¿</institution>
          ,
          <addr-line>Yekaterinburg, Russia, 06-Feb-2017, published at</addr-line>
        </aff>
      </contrib-group>
      <fpage>30</fpage>
      <lpage>41</lpage>
      <abstract>
        <p>Кафедра вычислительной математики и компьютерных наук, УрФУ (Екатеринбург) Рассматриваются стратегии организации обновляемых ассоциативных массивов во внешней памяти, применяемых для полнотекстового поиска. Изучаются вопросы создания индексов с разными видами ключа: одна форма слова, пара форм слов, последовательность форм слов. В зависимости от вида ключа, размер соответствующих ему данных различен, и структура их хранения может меняться. Приведены результаты экспериментов в контексте задачи полнотекстового поиска с учетом расстояния.</p>
      </abstract>
    </article-meta>
  </front>
  <body>
    <sec id="sec-1">
      <title>-</title>
      <p>1) Файл данных. Хранит списки словопозиций. Словопозиции для одного ключа должны храниться
преимущественно последовательно.
Способы создания инвертированных файлов</p>
      <p>Обновление индекса
Обновлением индекса назовем ситуацию, когда на основании одного набора документов был создан
индекс. Затем мы получили еще один набор документов, и требуется получить индекс, включающий
объединенные данные первоначальных и новых документов.
2.2</p>
      <p>
        Способ 1. Внешняя сортировка слиянием
Записываем в файл данных словопозиции, затем сортируем его таким образом, чтобы словопозиции,
соответствующие одному ключу, шли подряд. При обновлении индекса, если появились новые документы,
создается новый индекс и осуществляется процесс слияния предыдущего и нового индексов [
        <xref ref-type="bibr" rid="ref1">1</xref>
        ]. Чтобы не
сливать новый и старый индекс каждый раз, можно поддерживать одновременно нескольких индексов и
периодически сливать часть из них вместе, см., например, [
        <xref ref-type="bibr" rid="ref2">2</xref>
        ].
2.3
      </p>
      <p>
        Способ 2. Легко обновляемые индексы
Словопозиции ключа хранятся в наборе блоков, которые могут располагаться в разных местах файла
данных. Процесс создания индекса заключается в последовательном добавлении в индекс словопозиции, в
процессе чего набор блоков для конкретного ключа может меняться, например, могут добавляться новые
блоки. Обновление индекса осуществляется аналогично созданию индекса, т. е. заключается в
последовательном добавлении в существующий индекс новых записей. В качестве примера можно рассмотреть
[
        <xref ref-type="bibr" rid="ref3 ref4 ref5">3, 4, 5</xref>
        ].
      </p>
      <p>
        При создании данного индекса требуется больше операций ввода-вывода. Это может быть решено
различными способами организации кэш памяти и стратегиями формирования набора блоков. Также
необходимо, чтобы блоки одного ключа располагались преимущественно подряд для снижения числа операций
ввода-вывода при поиске. Алгоритмы, решающие данные проблемы, рассмотрены автором в [
        <xref ref-type="bibr" rid="ref5 ref6">5, 6</xref>
        ].
Преимущество данного способа в отсутствии процедуры слияния при обновлении индекса.
      </p>
      <p>Первый и второй способы имеют достоинства и недостатки, для способа 1 при обновлении индекса
требуется дорогостоящая операция слияния индексов, для способа 2 требуется существенно большее число
дисковых операций при создании индекса.</p>
      <p>
        Возможность более быстрого обновления индекса может быть важна. В [
        <xref ref-type="bibr" rid="ref10 ref7 ref8 ref9">7, 8, 9, 10</xref>
        ] автором
рассматриваются несколько вариантов индексов, где ключом является не одно слово или его форма, а несколько
форм слов. Эти дополнительные индексы могут применяться для значительного ускорения поиска, когда
поиск осуществляется с учетом расстояния. В [
        <xref ref-type="bibr" rid="ref8">8</xref>
        ] рассмотрен алгоритм построения подобных индексов. Он
включает в себя, в частности, разделение всего индексируемого массива текстов на части (размер которых
зависит от объема доступной оперативной памяти, обычно порядка 10-20 ГБ) и последовательное
добавление каждой части в индекс. В [
        <xref ref-type="bibr" rid="ref10 ref7">7, 10</xref>
        ] показано, что рассматриваемые дополнительные индексы позволяют
повысить скорость выполнения некоторых видов поисковых запросов в десятки раз.
3
      </p>
      <p>Структура легко обновляемого индекса
Таким образом, рассматриваемый нами индекс относится ко второму типу индексов. В данной
работе рассматриваются стратегии создания легко обновляемых индексов и результаты экспериментов.
Рассматривается новая стратегия создания цепочки блоков ограниченной длины, предназначенная для более
быстрого обновления индекса.</p>
      <p>Файл данных разбит на блоки фиксированного размера, называемые кластерами. Размер кластера
задается при создании индекса, например, 32 КБ.</p>
      <p>Потоком кластеров будем называть набор связанных кластеров, содержащий один список словопозиций.
Данные конкретного ключа хранятся в потоке кластеров. Примером потока кластеров является цепочка
одиночных кластеров.
4</p>
      <p>Цепочка одиночных кластеров
При добавлении первой словопозиции ключа в индекс мы можем выделять один кластер в нем. В
кластере зарезервируем свободное место, необходимое для хранения ссылки (номера) на другой кластер.</p>
      <p>Рис. 1: цепочка одиночных кластеров. Ключ K1 ссылается на первый и последний кластер.
Однако, просто создавать цепочки кластеров нельзя, так как число операций чтения при поиске должно
быть ограничено. Если каждый кластер будет в другом месте диска, то будет слишком много операций
ввода-вывода. Поэтому данный способ не используется. Рассмотрим несколько более сложных стратегий,
позволяющие создавать такой вид индекса.
5
5.1
Стратегии создания легко обновляемого индекса</p>
      <p>
        Стратегия C1
Для каждого потока кластеров храним не менее одного кластера в памяти во время создания индекса.
Поскольку ключей много, к примеру, в словаре русского языка около 200 тыс. базовых форм, их можно
разделить на группы, например, по 2000 ключей, и данные каждой группы добавлять в индекс
последовательно (как описано в [
        <xref ref-type="bibr" rid="ref5 ref8">5, 8</xref>
        ]). Один кластер в памяти для каждого потока кластеров является необходимым
условием. В целях повышения производительности объем этого кэша может быть больше, например, из
расчета по 10-15 кластеров для каждого потока.
      </p>
      <p>Обозначение C1 образовано от слова cluster и 1.
5.2</p>
      <p>Стратегия EM
5.3</p>
      <p>Стратегия PART
При малом размере данных словопозиции ключа могут храниться прямо в словаре, вместе с ключом.
Обозначение EM образовано от английского слова embedded.</p>
      <p>
        Если объем данных ключа меньше, чем половина кластера, то можно использовать часть кластера.
Кластер делится на равные части, каждая из которых может использоваться каким-то ключом. Вводим
виды кластеров, разделенные на 2 части, на 4, на 8 и т.д. Вначале используем кластер с минимальным
размером части. Когда свободное место заканчивается, переносим данные в кластер с большим размером
части. Когда размер данных превысит половину кластера, переносим данные в целый кластер. Детально
см. в [
        <xref ref-type="bibr" rid="ref5">5</xref>
        ].
      </p>
      <p>Рис. 2: кластер, разделенный на части
5.4</p>
      <p>
        Стратегия S
Если данных больше, чем 1 кластер, то вводим понятие сегмента кластеров. Сегмент – это несколько
последовательно располагающихся кластеров. Используем сегменты, число кластеров в которых – степень
2-х. Выделяем для данных сегмент и пишем в него последовательно. Если свободное место заканчивается,
выделяем сегмент вдвое большего размера, переносим в него данные, в первую половину. Параметром
N определяем максимальный размер сегмента. Если сегмент максимального размера заполнен, создаем
новый сегмент. При этом, если в наборе кластеров уже существует сегмент максимального размера, все
последующие сегменты также создаем максимального размера. Детально см. в [
        <xref ref-type="bibr" rid="ref5">5</xref>
        ].
      </p>
      <p>Пусть N = 8. На рис. 3 изображен поток кластеров, состоящий из трех сегментов. Два первых сегмента
полностью заполнены. В последнем заполнены полностью два первых кластера, а третий – частично.
Последние кластеры первых двух сегментов содержат ссылку на первый кластер следующего сегмента.
На практике размер максимального сегмента выбирается не менее нескольких десятков МБ. (несколько
сотен кластеров и более). Обозначение S образовано от английского слова segment.</p>
      <p>Рис. 3: сегменты кластеров
5.5</p>
      <p>Стратегия FL
Данные нескольких ключей могут одновременно храниться в одном потоке кластеров. Для этого к
каждой словопозиции добавляется тег – номер ключа.</p>
      <p>Допустим, есть два ключа:
K1, со списком словопозиций: (D1, P1), (D2, P2), . . . . ,
K2, со списком словопозиций: (F1, Q1), (F2, Q2), . . .
Можно сформировать список словопозиций:</p>
      <p>(D1, P1, 1), (F1, Q1, 2), (F2, Q2, 2), (D2, P2, 1), . . . ,
где в каждую исходную словопозицию добавлен номер ключа, 1 для K1, 2 для K2. Нумерация ключей
определена локально в пределах данного списка. Данная последовательность хранится в одном потоке
кластеров. Словопозиции в ней отсортированы по тем же критериям, как в исходных списках. Таким
образом, два (или более) ключа ссылаются на один поток кластеров. Соответствующий ключу номер (тег)
хранится в словаре.</p>
      <p>
        Длина подобного потока кластеров ограничена. Если для какого-то ключа объем данных превышает
заданный порог, то его данные извлекаются и сохраняются в новом, выделенном специально для этого
ключа потоке, в который уже словопозиции других ключей не помещаются и теги отсутствуют. Детально
см. в [
        <xref ref-type="bibr" rid="ref11 ref12">11, 12</xref>
        ].
5.7
5.7.1
Стратегия CH
      </p>
      <p>Цепочка кластеров с обратными ссылками ограниченной длины
В каком-то смысле вернемся к простому варианту. Используем цепочку одиночных кластеров. Но
ограничиваем ее размер. Добавляем данные в последний кластер. Если свободное место в последнем кластере
заканчивается, добавляем в цепочку новый кластер, прописывая сразу в нем ссылку на предыдущий. Если
кластеров становится много (например, больше 9), то преобразуем цепочку кластеров в сегмент кластеров
и переходим к стратегии S. То есть выделяем пустой сегмент, считываем все кластеры цепочки, сохраняем
данные в новом сегменте, а кластеры цепочки помещаем в список свободных кластеров для
переиспользования. Стратегия CH не рассмотрена ранее.</p>
      <p>Заметим, что есть два варианта организации цепочки кластеров. В начале статьи была приведена
цепочка кластеров, когда мы в кластере указываем ссылку на следующий кластер цепочки. В этом же разделе
(рис. 5) мы в кластере указываем ссылку на предыдущий кластер цепочки. Это позволяет уменьшить
число дисковых операций при записи данных, но чтение данных требуется осуществлять с конца цепочки
кластеров. Это означает, что при поиске вся цепочка кластеров должна быть считана в память для доступа
к первой словопозиции. Это всегда возможно, так как длина цепочки ограничена.</p>
      <p>Рис. 5: цепочка кластеров с обратными ссылками
Обозначение CH образовано от английского слова chain.
5.7.2</p>
      <p>Цепочка сегментов с обратными ссылками ограниченной длины
Если при добавлении нового кластера в цепочку какое-то количество предыдущих кластеров
оказывается в кэше, мы можем содержимое этих кластеров перенести в новое место, располагая друг за другом, см.
рис. 6. Таким образом, мы можем получить не цепочку кластеров, а цепочку сегментов кластеров. Момент
перехода к стратегии S зависит не от числа кластеров в цепочке, а от числа сегментов в ней, потому что
число сегментов определяет число обращений к разным местам диска при чтении данных этой цепочки.</p>
      <p>Далее опишем, как в общем случае выглядит алгоритм добавления нового кластера в цепочку.
2) Копируем содержимое сегментов из кэша в отдельный буфер.
3) Выделяем новый сегмент большого размера (размер такой, чтобы поместить в него данные сегментов
цепочки, скопированные на шаге 2 и данные нового кластера).
4) Скопированные на шаге 2 сегменты освобождаем.
5) В новом большом сегменте прописываем ссылку на последний сегмент цепочки, который мы не
сливаем.
6) Записываем в новый сегмент данные сливаемых сегментов и данные нового кластера. Было выявлено,
что имеет смысл сливать не менее двух сегментов (плюс новый кластер). Если сливать просто один
последний сегмент и новый кластер, то образуется слишком много свободных сегментов, которые
накапливаются (на шаге 4 мы освобождаем старые сегменты, что означает, что их адреса помещаются
в список свободных сегментов, и они могут быть повторно использованы).
5.7.3</p>
      <p>
        Ограничение на длину цепочки сегментов
Это ограничение должно определяться, исходя из ограничения на суммарное число операций
вводавывода, выполняемых при поиске. Эксперименты показали, что при выборе числа 9 время поиска не
изменяется, по сравнению с проведенными в [
        <xref ref-type="bibr" rid="ref10">10</xref>
        ] экспериментами. Имеет смысл также задать для разных
потоков кластеров разные граничные условия. Например, выбирать для конкретного потока кластеров
ограничение длины из диапазона 7-9 случайным образом или в зависимости от адреса первого кластера.
Этот подход позволяет увеличить вероятность того, что свертывание цепочки сегментов (переход от CH к
S) будет происходить для разных потоков кластеров при выполнении разных обновлений индекса.
5.8
      </p>
      <p>Стратегия SR
Модификация стратегии FL. Вместо выделения специальной области в индексе, используем отдельный
индекс – индекс коротких записей (ИКЗ). Потоку кластеров может соответствовать запись в ИЗК, назовем
ее SR-записью. Эта запись представляет собой список словопозиций и хранится в наборе малых блоков
(например, 128 байта каждый).</p>
      <p>Размер данных SR-записи ограничен размером кластера. Как только данных становится больше,
переносим данные из SR-записи в ее поток кластеров.</p>
      <p>При завершении обработки группы ключей, данные ИКЗ сохраняются в специальном файле. При старте
обновления индекса все данные ИКЗ считываются в память. Чтение и запись данных ИКЗ осуществляется
последовательно с буферизацией.</p>
      <p>Объем кэша ИКЗ ограничен. Если потоков кластеров становится слишком много, для новых потоков
стратегия перестает применяться. Эта стратегия не рассмотрена ранее.</p>
      <p>Цель данной стратегии – оптимизировать хранение данных в FL-кластерах. Если для потока кластеров
мы выделяем целый FL-кластер, то мы не знаем, насколько он будет заполнен. Может быть, FL-кластер
будет заполнен наполовину, или даже меньше, но записать этот кластер в файл мы должны целиком при
завершении обновления индекса. То есть объем ввода-вывода получается больше, чем объем хранимых
данных. В ИКЗ же применяем малые блоки, размер которых существенно меньше размера кластера.</p>
      <p>Применение стратегии SR вместе с CH позволяет избежать чтения кластеров цепочки при обновлении
индекса. Мы стремимся держать кластеры цепочки полностью заполненными. Как только мы накопили
в SR-записи объем, превышающий размер кластера, мы переносим в цепочку кластеров ровно столько
данных, чтобы последний кластер цепочки был полностью заполнен (то есть, всегда добавляем в цепочку
новый, полностью заполненный кластер). Если при этом в SR-записи было больше данных, чем требовалось
для заполнения свободного места в последнем кластере цепочки, остаток оставляем в SR записи. Поэтому
при каждом переносе данных в цепочку кластеров нам не требуется читать последний кластер цепочки,
так как он: 1) уже заполнен, 2) мы сохраняем ссылку на предыдущий кластер в новом, а не наоборот.</p>
      <p>На рис. 7 изображена цепочка сегментов с обратными ссылками и SR-записью, состоящей из четырех
малых блоков (эти блоки при добавлении данных находятся в оперативной памяти). Ключ K1 ссылается
на первый кластер цепочки, последний заполненный кластер и на SR-запись.</p>
      <p>Рис. 7: цепочка кластеров с SR-записью
Обозначение SR образовано от английских слов short; record.
5.9</p>
      <p>
        Стратегия DS
Используем два файла, один для больших дисковых операций, другой для малых. При этом при записи
малых дисковых операций упаковываем их в большой буфер и сохраняем его (требуется также хранить
таблицу исходных и физических адресов). Несколько дисковых операций, с адресами A, B, C,
упаковываются в один большой буфер и получают в нем адреса a, b, c. Отдельно есть таблица преобразования: A !
a, B ! b, C ! c. Детально см. в [
        <xref ref-type="bibr" rid="ref9">9</xref>
        ].
      </p>
      <p>Обозначение DS образовано от distributed store.
5.10</p>
      <p>Диаграмма состояний потока кластеров
На рис. 8 показано, как текущая стратегия хранения данных в потоке кластеров может меняться в
зависимости от настроек и объема данных.</p>
      <p>Стратегия TAG не включена в рисунок, так как она реализуется на уровне словаря.</p>
      <p>Стратегия DS реализуется на уровне организации записи и чтения в файл индекса, и поэтому также не
отображена на рисунке.</p>
      <p>Стратегия C1 применяется неявно для каждой из стратегий, изображенных на рисунке.
В зависимости от объема данных мы можем начать использовать стратегию EM. Как только данных
становится больше, переходим к стратегии PART либо используем SR (при этом на каком-то этапе может
использоваться только SR, а кластер в файле с данными не выделяться).</p>
      <p>В случае выбора стратегии PART, далее, когда объем данных превысит размер части для кластера,
разделенного пополам, мы используем универсальную стратегию S либо промежуточную стратегию CH.
Стратегия FL может применяться в качестве оптимизации. Обозначение S+FL означает применение
одновременно стратегии S как основной и FL – как дополнительной.</p>
      <p>В случае выбора SR мы далее выбираем либо S, либо CH, с применением SR в качестве
оптимизации. PART в этом случае не используется, так как если мы уже решили хранить для некоторого потока
кластеров отдельно в индексе коротких записей объем данных размером до размера одного кластера, то
использовать PART смысла нет, так как она применяется для объемов, не превышающих один кластер.
6
6.1</p>
      <p>Виды запросов
Применение легко обновляемых индексов для полнотекстового поиска
Рассмотрим несколько запросов.</p>
      <p>Time and a world Yes.</p>
      <p>The Who who are you.</p>
      <p>End of days.
Скажи мне кто твой друг.</p>
      <p>Слова в текстах встречаются с разной частотой. Наибольшую сложность представляют запросы,
включающие часто встречающиеся слова. Запрос с такими словами, как “and”, “who”, может выполняться долго
с использованием обычного индекса, если ключ – это форма слова, а значение – список вхождений данного
слова в текстах.</p>
      <p>
        Если использовать дополнительные индексы, где ключом является несколько форм слов, выполнение
ряда запросов можно ускорить в десятки раз [
        <xref ref-type="bibr" rid="ref10 ref7">7, 10</xref>
        ].
6.2
      </p>
      <p>Три вида слов
Разделим все слова на 3 группы.
1) стоп слова, например: предлоги, местоимения,
2) часто используемые слова,
3) остальные.</p>
      <p>Используем морфологический анализатор. Для каждой словоформы, входящей в словарь анализатора,
он возвращает список номеров базовых форм слов. Такое слово мы назовем известным словом. Номер
базовой формы – это число в диапазоне от 0 до WordsCount – 1, где WordsCount – число различных
базовых форм (около 260 тыс. для используемого словаря).</p>
      <p>Если слово не входит в словарь анализатора, то будем считать, что его базовая форма совпадает с самим
словом. Такое слово назовем неизвестным.</p>
      <p>Базовые формы слова также называются леммами, а сам процесс получения набора лемм по
словоформе – лемматизацией. Разделение слов на три группы также применяется и к леммам.
6.3</p>
      <p>
        Три вида индексов
В проведенных экспериментах использовалась структура индексов, описанная в [
        <xref ref-type="bibr" rid="ref10">10</xref>
        ]. Применяем три
вида индексов.
      </p>
      <p>1) Обычный индекс. Ключ – лемма слова.
2) Расширенный индекс. Ключ – пара лемм (w,v) (словопозиция формируется, когда слова располагаются
близко в тексте).
6.4</p>
      <p>Описание экспериментов
Проиндексировано 71.5 ГБ текста. Далее приведены результаты трех экспериментов создания индексов.
В каждом из трех экспериментов применялся разный набор стратегий:
1) C1+EM+PART+S+FL+TAG (первые 6 стратегий).
2) Все, что в 1, и CH+SR.
3) Все, что в 2, и DS.</p>
      <p>Суммарный размер индекса в каждом случае – около 400 ГБ. В каждом эксперименте измеряются
следующие показатели:
1) Суммарный объем прочитанных и записанных данных.
2) Суммарное число операций ввода-вывода.</p>
      <p>Объем документов был разделен на две части. Вначале создан индекс для первой части. Затем в него
добавлена вторая часть (обновление индекса).</p>
      <p>
        Таблица 1: параметры
Параметр
Размер кластера
Число кластеров в кэше на один поток кластеров
Критерий малой операции ввода вывода (для DS, [
        <xref ref-type="bibr" rid="ref9">9</xref>
        ])
Размер кэша файла данных (кластеров)
Максимальная длина в сегментах цепочки кластеров для CH
Число групп известных лемм (вычисляемый параметр в зависимости
от объема кэша и числа кластеров в кэше на один поток кластеров)
Число групп неизвестных лемм
Значение
32 КБ
45
6 32 КБ
1 ГБ
9
Обычный индекс известных лемм
Обычный индекс неизвестных лемм
Расширенные индексы, w, v – известные
Расширенные индексы, w – известная, v – неизвестная
Индекс последовательностей стоп-лемм
Вид индекса
Обычный индекс известных лемм
Обычный индекс неизвестных лемм
Расширенные индексы, w, v – известные
Расширенные индексы, w – известная, v – неизвестная
Индекс последовательностей стоп-лемм
Таблица 3: количество операций ввода-вывода
Ershovo, Moscow, Russia, October 11-14, 2016 (in Russian). = А. Б. Веретенников. О применении
дополнительных индексов часто встречающихся слов для полнотекстового поиска. Аналитика и
управление данными в областях с интенсивным использованием данных. XVIII Международная конференция
DAMDID / RCDL’2016, 217-224, 11-14 октября 2016 года, Ершово, Москва.
Alexander B. Veretennikov
Ural Federal University (Yekaterinburg, Russia)
Keywords: full-text search, search engines, inverted files, additional indexes.
      </p>
      <p>We consider strategies of organization of easily updatable associative arrays in external memory. These arrays
are used for full-text search. We study indexes with different keys: single word form, two word forms, sequence
of word forms. Structure of storage depends on the size of key’s data. Results of the experiments are given in
the context of the proximity full-text search by means of additional indexes.</p>
    </sec>
  </body>
  <back>
    <ref-list>
      <ref id="ref1">
        <mixed-citation>
          [1]
          <string-name>
            <given-names>J.</given-names>
            <surname>Zobel</surname>
          </string-name>
          ,
          <string-name>
            <given-names>A.</given-names>
            <surname>Moffat</surname>
          </string-name>
          .
          <article-title>Inverted files for text search engines</article-title>
          .
          <source>ACM Computing Surveys</source>
          ,
          <volume>38</volume>
          (
          <issue>2</issue>
          ), Article 6,
          <year>2006</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref2">
        <mixed-citation>
          [2]
          <string-name>
            <given-names>N.</given-names>
            <surname>Lester</surname>
          </string-name>
          ,
          <string-name>
            <given-names>A.</given-names>
            <surname>Moffat</surname>
          </string-name>
          ,
          <string-name>
            <surname>J. Zobel.</surname>
          </string-name>
          <article-title>Fast On-Line Index Construction by Geometric Partitioning</article-title>
          .
          <source>In CIKM '05: Proceedings of the 14th ACM international conference on Information and knowledge management</source>
          ,
          <fpage>776</fpage>
          -
          <lpage>783</lpage>
          ,
          <year>2005</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref3">
        <mixed-citation>
          [3]
          <string-name>
            <given-names>A.</given-names>
            <surname>Tomasic</surname>
          </string-name>
          ,
          <string-name>
            <given-names>H.</given-names>
            <surname>Garcia-Molina</surname>
          </string-name>
          ,
          <string-name>
            <given-names>K.</given-names>
            <surname>Shoens</surname>
          </string-name>
          .
          <article-title>Incremental updates of inverted lists for text document retrieval</article-title>
          ,
          <source>In Proc. ACMSIGMOD Int. Conf. on the Management of Data</source>
          , Minneapolis, Minnesota,
          <fpage>289</fpage>
          -
          <lpage>300</lpage>
          ,
          <year>1994</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref4">
        <mixed-citation>
          [4]
          <string-name>
            <given-names>E. W.</given-names>
            <surname>Brown</surname>
          </string-name>
          ,
          <string-name>
            <given-names>J. P.</given-names>
            <surname>Callan</surname>
          </string-name>
          ,
          <string-name>
            <given-names>W. B.</given-names>
            <surname>Croft</surname>
          </string-name>
          .
          <article-title>Fast incremental indexing for full-text information retrieval</article-title>
          .
          <source>In Proceedings of the International Conference on Very Large Databases</source>
          ,
          <fpage>192</fpage>
          -
          <lpage>202</lpage>
          , Santiago, Chile,
          <year>1994</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref5">
        <mixed-citation>
          [5]
          <string-name>
            <given-names>A. B.</given-names>
            <surname>Veretennikov</surname>
          </string-name>
          .
          <article-title>Effective Indexing of Text Documents using CLB-Trees</article-title>
          .
          <source>Control systems and information technologies</source>
          ,
          <volume>35</volume>
          (
          <issue>1</issue>
          .1):
          <fpage>134</fpage>
          -
          <lpage>139</lpage>
          ,
          <year>2009</year>
          (in Russian).
          <source>= А. Б. Веретенников</source>
          .
          <article-title>Эффективная индексация тексто- вых документов с использованием CLB-деревьев</article-title>
          .
          <source>Системы управления и информационные технологии</source>
          ,
          <volume>35</volume>
          (
          <issue>1</issue>
          .1):
          <fpage>134</fpage>
          -
          <lpage>139</lpage>
          ,
          <year>2009</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref6">
        <mixed-citation>
          [6]
          <string-name>
            <given-names>A. B.</given-names>
            <surname>Veretennikov</surname>
          </string-name>
          .
          <article-title>About phrases search in full-text index</article-title>
          .
          <source>Control systems and information technologies</source>
          ,
          <volume>48</volume>
          (
          <issue>2</issue>
          .1):
          <fpage>125</fpage>
          -
          <lpage>130</lpage>
          ,
          <year>2012</year>
          (in Russian).
          <source>= А. Б. Веретенников</source>
          .
          <article-title>О поиске фраз и наборов слов в полнотекстовом индексе</article-title>
          .
          <source>Системы управления и информационные технологии</source>
          ,
          <volume>48</volume>
          (
          <issue>2</issue>
          .1):
          <fpage>125</fpage>
          -
          <lpage>130</lpage>
          ,
          <year>2012</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref7">
        <mixed-citation>
          [7]
          <string-name>
            <given-names>A. B.</given-names>
            <surname>Veretennikov</surname>
          </string-name>
          .
          <article-title>Using additional indexes for fast full-text searching phrases that contains frequently used words</article-title>
          .
          <source>Control systems and information technologies</source>
          ,
          <volume>52</volume>
          (
          <issue>2</issue>
          ):
          <fpage>61</fpage>
          -
          <lpage>66</lpage>
          ,
          <year>2013</year>
          (in Russian).
          <source>= А</source>
          . Б.
          <article-title>Вере- тенников. Использование дополнительных индексов для более быстрого полнотекстового поиска фраз, включающих часто встречающиеся слова</article-title>
          .
          <source>Системы управления и информационные технологии</source>
          ,
          <volume>52</volume>
          (
          <issue>2</issue>
          ):
          <fpage>61</fpage>
          -
          <lpage>66</lpage>
          ,
          <year>2013</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref8">
        <mixed-citation>
          [8]
          <string-name>
            <given-names>A. B.</given-names>
            <surname>Veretennikov</surname>
          </string-name>
          .
          <article-title>Creating additional indexes for fast full-text searching phrases that contains frequently used words</article-title>
          .
          <source>Control systems and information technologies</source>
          ,
          <volume>63</volume>
          (
          <issue>1</issue>
          ):
          <fpage>27</fpage>
          -
          <lpage>33</lpage>
          ,
          <year>2016</year>
          (in Russian).
          <source>= А</source>
          . Б.
          <article-title>Ве- ретенников. Создание дополнительных индексов для более быстрого полнотекстового поиска фраз, включающих часто встречающиеся слова</article-title>
          .
          <source>Системы управления и информационные технологии</source>
          ,
          <volume>63</volume>
          (
          <issue>1</issue>
          ):
          <fpage>27</fpage>
          -
          <lpage>33</lpage>
          ,
          <year>2016</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref9">
        <mixed-citation>
          [9]
          <string-name>
            <given-names>A. B.</given-names>
            <surname>Veretennikov</surname>
          </string-name>
          .
          <article-title>Using additional indexes of frequently used words for full-text search. Data Analytics and Management in Data Intensive Domains XVIII International Conference</article-title>
          ,
          <source>DAMDID/RCDL</source>
          <year>2016</year>
          ,
          <volume>217</volume>
          -
          <fpage>224</fpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref10">
        <mixed-citation>
          [10]
          <string-name>
            <given-names>A. B.</given-names>
            <surname>Veretennikov</surname>
          </string-name>
          .
          <article-title>Efficient full-text search by means of additional indexes of frequently used words</article-title>
          .
          <source>Control systems and information technologies</source>
          ,
          <volume>66</volume>
          (
          <issue>4</issue>
          ):
          <fpage>52</fpage>
          -
          <lpage>60</lpage>
          ,
          <year>2016</year>
          (in Russian).
          <source>= А. Б. Веретенников</source>
          .
          <article-title>Эф- фективный полнотекстовый поиск с использованием дополнительных индексов часто встречающихся слов</article-title>
          .
          <source>Системы управления и информационные технологии</source>
          ,
          <volume>66</volume>
          (
          <issue>4</issue>
          ):
          <fpage>52</fpage>
          -
          <lpage>60</lpage>
          ,
          <year>2016</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref11">
        <mixed-citation>
          [11]
          <string-name>
            <given-names>A. B.</given-names>
            <surname>Veretennikov</surname>
          </string-name>
          .
          <article-title>On CLB-tree building method optimization</article-title>
          .
          <source>Proceedings of the 41th all-russian Youth School-conference “Modern Problems in Mathematics and its Applications</source>
          ”
          <fpage>429</fpage>
          -
          <lpage>435</lpage>
          , Yekaterinburg,
          <year>2010</year>
          (in Russian).
          <source>= А. Б. Веретенников</source>
          .
          <article-title>О методе оптимизации создания CLB-дерева. Проблемы теоретической и прикладной математики: Тезисы 41-й Всероссийской молодежной конференции</article-title>
          ,
          <fpage>429</fpage>
          -
          <lpage>435</lpage>
          , Екатерин- бург:
          <source>УрО РАН</source>
          ,
          <year>2010</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref12">
        <mixed-citation>
          [12]
          <string-name>
            <given-names>A. B.</given-names>
            <surname>Veretennikov</surname>
          </string-name>
          .
          <article-title>On building easy updatable full-text indexes. Digital libraries: advanced methods and technologies, digital collections</article-title>
          .
          <source>The Tenth Anniversary of All-Russian Research Conference 149-154</source>
          , Dubna,
          <year>2008</year>
          , (in Russian).
          <source>= А. Б. Веретенников</source>
          .
          <article-title>Создание легко обновляемых текстовых индексов. Элек- тронные библиотеки: перспективные методы и технологии, электронные коллекции: Труды Десятой Всероссийской научной конференции “RCDL'</article-title>
          <year>2008</year>
          ”,
          <fpage>149</fpage>
          -
          <lpage>154</lpage>
          , Дубна: ОИЯИ,
          <year>2008</year>
          .
        </mixed-citation>
      </ref>
    </ref-list>
  </back>
</article>