Текстовый индекс
Практически обработку текстовой информации в Oracle Text обеспечивает текстовый индекс. Содержательно он организует хранение «обращенного списка», который по предъявленному поисковому слову выдает список пар <документ, словоместо>. Для этого он хранит список документов, позиций словоформ в документах и одно или несколько индексируемых слов в каждой позиции.
Технически текстовый индекс устроен сложнее обычных B-древовидного или же поразрядного индексов хотя бы тем, что реализован сразу группой объектов и группой структур хранения. В этом легко удостовериться:
CTX> COLUMN object_name FORMAT A30 CTX> COLUMN object_type FORMAT A30 CTX> COLUMN segment_name FORMAT A30 CTX> COLUMN segment_type FORMAT A30 CTX> SELECT object_name, object_type FROM user_objects ORDER BY 2, 1;
OBJECT_NAME OBJECT_TYPE ------------------------------ ------------------------------ DOCS_VC2DOC_IDX INDEX DR$DOCS_VC2DOC_IDX$X INDEX SYS_IOT_TOP_51619 INDEX SYS_IOT_TOP_51624 INDEX SYS_LOB0000051616C00006$$ LOB SYS_LOB0000051621C00002$$ LOB DOCS TABLE DR$DOCS_VC2DOC_IDX$I TABLE DR$DOCS_VC2DOC_IDX$K TABLE DR$DOCS_VC2DOC_IDX$N TABLE DR$DOCS_VC2DOC_IDX$R TABLE
CTX> SELECT segment_name, segment_type FROM user_segments ORDER BY 2, 1;
SEGMENT_NAME SEGMENT_TYPE ------------------------------ ------------------------------ DR$DOCS_VC2DOC_IDX$X INDEX SYS_IOT_TOP_51619 INDEX SYS_IOT_TOP_51624 INDEX SYS_IL0000051616C00006$$ LOBINDEX SYS_IL0000051621C00002$$ LOBINDEX SYS_LOB0000051616C00006$$ LOBSEGMENT SYS_LOB0000051621C00002$$ LOBSEGMENT DOCS TABLE DR$DOCS_VC2DOC_IDX$I TABLE DR$DOCS_VC2DOC_IDX$R TABLE
В обоих запросах все объекты БД и структуры хранения, кроме DOCS, принадлежат текстовому индексу. Точнее, в результате команды CREATE INDEX docs_vc2doc_idx ... индекс DOCS_VC2DOC_IDX (типа DOMAIN) появился только как логический объект в БД; технически его реализуют четыре возникшие служебные таблицы:
Таблица DR$DOCS_VC2DOC_IDX$I.
Хранит перечень всех словоформ, попавших в индекс, внутренний номер документа («DOCID») и список позиций словоформ в документе. Вторичные, связанные с ней объекты:
- индекс DR$DOCS_VC2DOC_IDX$X (обычный, типа NORMAL),
- сегменты типа LOBSEGMENT и LOBINDEX для хранения данных поля TOKEN_INFO типа BLOB.
Таблица DR$DOCS_VC2DOC_IDX$K.
Хранит соответствие DOCID адресу ROWID строки с текстом или ссылкой на текст. Индексно-организованная таблица, хранится в структуре индекса. Таблица DR$DOCS_VC2DOC_IDX$R.
Хранит список для обратного поиска: ROWID по DOCID. Вторичные, связанные с ней объекты:
сегменты типа LOBSEGMENT и LOBINDEX для хранения данных поля DATA типа BLOB.
Таблица DR$DOCS_VC2DOC_IDX$N.
Хранит список удаленных документов (DOCID) пополняющийся при оптимизации текстового индекса. Индексно-организованная таблица, хранится в структуре индекса.
Пример выдачи из таблицы DR$DOCS_VC2DOC_IDX$I:
CTX> SELECT token_text, token_count FROM dr$docs_vc2doc_idx$i;
TOKEN_TEXT TOKEN_COUNT ------------------------------------------------- ----------- LAMB 2 LITTLE 2 MARY 1 STAR 1 TWINKLE 1
Еще одно отличие текстового индекса от обычного в том, что он не правится автоматически при правке документа. Например:
CTX> UPDATE docs SET vc2doc = 'This Land is my land' WHERE doc_id = 3;
1 row updated.
CTX> COMMIT;
Commit complete.
CTX> SELECT token_text, token_count FROM dr$docs_vc2doc_idx$i;
TOKEN_TEXT TOKEN_COUNT ------------------------------------------------- ----------- LAMB 2 LITTLE 2 MARY 1 STAR 1 TWINKLE 1
В силу громоздкости текстового индекса сведения о необходимых исправлениях собираются в отдельной таблице, а сама правка выполняется по мере надобности вручную:
CTX> SELECT pnd_index_name, pnd_rowid FROM
ctx_user_pending;
PND_INDEX_NAME PND_ROWID ---------------------------- ------------------
DOCS_VC2DOC_IDX AAAMm2AAEAAAABAAAC
CTX> EXECUTE
CTX_DDL.SYNC_INDEX ( 'docs_vc2doc_idx' )
PL/SQL procedure successfully completed.
CTX> /
no rows selected
CTX> SELECT token_text, token_count FROM dr$docs_vc2doc_idx$i;
TOKEN_TEXT TOKEN_COUNT ------------------------------------------------- ----------- LAMB 2
LAND 1LITTLE 2 MARY 1 STAR 1 TWINKLE 1
(Синхронизировать индекс можно и командой ALTER INDEX, но сейчас фирма Oracle этого не советует).
Стандартный прием - создать задание для плановой корректировки текстового индекса по расписанию.
Содержание раздела