25.8. Текстовый индекс

Практически обработку текстовой информации в Oracle Text обеспечивает текстовый индекс. Содержательно он организует хранение «обращенного списка», который по предъявленному поисковому слову выдает список пар <документ, словоместо>. Для этого он хранит список документов, позиций словоформ в документах и одно или несколько индексируемых слов в каждой позиции.

Технически текстовый индекс устроен сложнее обычных B-древовидного или же поразрядного индексов хотя бы тем, что реализован сразу группой объектов и группой структур хранения. Вэтомлегкоудостовериться:

38. SQL> COLUMN object_name FORMAT A30

39. SQL> COLUMN object_type FORMAT A30

40. SQL> COLUMN segment_name FORMAT A30

41. SQL> COLUMN segment_type FORMAT A30

42. SQL> SELECT object_name, object_type FROM user_objects ORDER BY 2, 1;

OBJECT_NAME OBJECT_T

------------------------------ --------

DOCS_VC2DOC_IDX INDEX

DR$DOCS_VC2DOC_IDX$X INDEX

SYS_IOT_TOP_34422 INDEX

SYS_IOT_TOP_34427 INDEX

SYS_LOB0000034419C00006$$ LOB

SYS_LOB0000034424C00002$$ 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

43. SQL> 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_34422 INDEX

SYS_IOT_TOP_34427 INDEX

SYS_IL0000034419C00006$$ LOBINDEX

SYS_IL0000034424C00002$$ LOBINDEX

SYS_LOB0000034419C00006$$ LOBSEGMENT

SYS_LOB0000034424C00002$$ 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) появился только как логический объект в БД; технически его реализуют четыре возникшие служебные таблицы:

44. Пример выдачи из таблицы DR$DOCS_VC2DOC_IDX$I.

SQL> SELECT token_text, token_count FROM dr$docs_vc2doc_idx$i;

TOKEN_TEXT TOKEN_COUNT

---------------------------------------------------------------- -----------

БРАТЬ 1

ЗВЕЗДА 1

ИМЕЕТ 1

ЛАМПУ 2

ЛУЧИК 1

МАЛЕНЬКАЯ 1

МАЛЕНЬКУЮ 1

МАША 1

НЕЛЬЗЯ 1

ЭТУ 1

45. Еще одно отличие текстового индекса от обычного в том, что он не правится автоматически при изменении документа. Например, выполните обновление:

SQL> UPDATE docs SET vc2doc = 'Эту лампу нельзя лапать' WHERE doc_id = 3;

46. Завершите транзакцию: SQL> COMMIT;

47. SQL> SELECT token_text, token_count FROM dr$docs_vc2doc_idx$i;

TOKEN_TEXT TOKEN_COUNT

---------------------------------------------------------------- -----------

БРАТЬ 1

ЗВЕЗДА 1

ИМЕЕТ 1

ЛАМПУ 2

ЛУЧИК 1

МАЛЕНЬКАЯ 1

МАЛЕНЬКУЮ 1

МАША 1

НЕЛЬЗЯ 1

ЭТУ 1

48. Как видите новое слово лапать не появилось!

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

SQL>SELECT pnd_index_name, pnd_rowid FROM ctx_user_pending;

PND_INDEX_NAME PND_ROWID

------------------------------ ------------------

DOCS_VC2DOC_IDX AAAIZxAAJAAACHGAAC

50. SQL>EXECUTE CTX_DDL.SYNC_INDEX ( 'docs_vc2doc_idx' )

51. SQL> SELECT token_text, token_count FROM dr$docs_vc2doc_idx$i;

БРАТЬ 1

ЗВЕЗДА 1

ИМЕЕТ 1

ЛАМПУ 2

ЛУЧИК 1

МАЛЕНЬКАЯ 1

МАЛЕНЬКУЮ 1

МАША 1

НЕЛЬЗЯ 1

ЭТУ 1

ЛАПАТЬ 1

52. Как видите теперь индекс обновлен!

53. Можно и по другому: SQL> UPDATE docs SET vc2doc = 'Эту лампу и выключатель нельзя лапать' WHERE doc_id = 3;

54. SQL> COMMIT;

55. SQL> SELECT token_text, token_count FROM dr$docs_vc2doc_idx$i;

Выключатель не появился!

56. Обновитеиндекс: SQL>ALTER INDEX docs_vc2doc_idx REBUILD;

57. SQL> SELECT token_text, token_count FROM dr$docs_vc2doc_idx$i;

Выключатель есть!