CTX_ANL в PL/SQL — полное руководство с 50 примерами

🟢 CTX_ANL в PL/SQL. Введение

Oracle Text — механизм полнотекстового поиска в Oracle Database.
Пакет CTX_ANL позволяет добавлять и удалять пользовательские словари для AUTO_LEXER,
чтобы учитывать отраслевую лексику, сокращения и новые слова.

Основные процедуры:

  • ADD_DICTIONARY(name, language, dictionary CLOB) — добавление словаря,
  • DROP_DICTIONARY(name, language, dictionary CLOB) — удаление словаря.

Строки словаря разделяются переносами строк. Используются директивы:
STEM (корни слов), COMPOUND (сложные слова), части речи и признаки (род, склонение).
Ошибки формата выявляются при создании/изменении индекса (например, DRG-13710).

50 примеров использования CTX_ANL

Основные операции (1–10)

1. Создание преференса AUTO_LEXER

BEGIN
  CTX_DDL.CREATE_PREFERENCE('a_lex','AUTO_LEXER');
END;

2. Добавление простого словаря

DECLARE
  dict CLOB := 'STEM	dog	noun';
BEGIN
  CTX_ANL.ADD_DICTIONARY('dict1','ENGLISH',dict);
END;

3. Удаление словаря

DECLARE
  dict CLOB := 'STEM	dog	noun';
BEGIN
  CTX_ANL.DROP_DICTIONARY('dict1','ENGLISH',dict);
END;

4. Добавление словаря с compound-словом

DECLARE
  dict CLOB := 'COMPOUND	help|desk	STEM	helpdesk	noun';
BEGIN
  CTX_ANL.ADD_DICTIONARY('dict2','ENGLISH',dict);
END;

5. Удаление compound-словаря

DECLARE
  dict CLOB := 'COMPOUND	help|desk	STEM	helpdesk	noun';
BEGIN
  CTX_ANL.DROP_DICTIONARY('dict2','ENGLISH',dict);
END;

6. Несколько STEM в словаре

DECLARE
  dict CLOB := 'STEM	cat	noun' || CHR(10) || 'STEM	cats	nounPlural';
BEGIN
  CTX_ANL.ADD_DICTIONARY('dict3','ENGLISH',dict);
END;

7. Удаление словаря с несколькими STEM

DECLARE
  dict CLOB := 'STEM	cat	noun' || CHR(10) || 'STEM	cats	nounPlural';
BEGIN
  CTX_ANL.DROP_DICTIONARY('dict3','ENGLISH',dict);
END;

8. Proper noun в словаре

DECLARE
  dict CLOB := 'STEM	Oracle	nounProper';
BEGIN
  CTX_ANL.ADD_DICTIONARY('dict4','ENGLISH',dict);
END;

9. Удаление словаря с proper noun

DECLARE
  dict CLOB := 'STEM	Oracle	nounProper';
BEGIN
  CTX_ANL.DROP_DICTIONARY('dict4','ENGLISH',dict);
END;

10. Признак рода в словаре

DECLARE
  dict CLOB := 'STEM	actor	noun	genderMasculine';
BEGIN
  CTX_ANL.ADD_DICTIONARY('dict5','ENGLISH',dict);
END;

Морфология и признаки (11–20)

11. Женский род

DECLARE
  dict CLOB := 'STEM	actress	noun	genderFeminine';
BEGIN
  CTX_ANL.ADD_DICTIONARY('dict6','ENGLISH',dict);
END;

12. Средний род

DECLARE
  dict CLOB := 'STEM	child	noun	genderNeuter';
BEGIN
  CTX_ANL.ADD_DICTIONARY('dict7','ENGLISH',dict);
END;

13. Прилагательное

DECLARE
  dict CLOB := 'STEM	beautiful	adjective';
BEGIN
  CTX_ANL.ADD_DICTIONARY('dict8','ENGLISH',dict);
END;

14. Глагол

DECLARE
  dict CLOB := 'STEM	run	verb';
BEGIN
  CTX_ANL.ADD_DICTIONARY('dict9','ENGLISH',dict);
END;

15. Несколько частей речи

DECLARE
  dict CLOB := 'STEM	dance	verb, noun';
BEGIN
  CTX_ANL.ADD_DICTIONARY('dict10','ENGLISH',dict);
END;

16. Русский: declensionHard

DECLARE
  dict CLOB := 'STEM	стол	noun	declensionHard';
BEGIN
  CTX_ANL.ADD_DICTIONARY('dict11','RUSSIAN',dict);
END;

17. Русский: declensionSoft

DECLARE
  dict CLOB := 'STEM	мать	noun	declensionSoft';
BEGIN
  CTX_ANL.ADD_DICTIONARY('dict12','RUSSIAN',dict);
END;

18. Французский словарь

DECLARE
  dict CLOB := 'STEM	maison	noun';
BEGIN
  CTX_ANL.ADD_DICTIONARY('dict13','FRENCH',dict);
END;

19. Немецкий словарь

DECLARE
  dict CLOB := 'STEM	Haus	noun';
BEGIN
  CTX_ANL.ADD_DICTIONARY('dict14','GERMAN',dict);
END;

20. Русский словарь (простой STEM)

DECLARE
  dict CLOB := 'STEM	мир	noun';
BEGIN
  CTX_ANL.ADD_DICTIONARY('dict15','RUSSIAN',dict);
END;

Сложные конструкции (21–30)

21. Compound из трёх частей (EN)

DECLARE
  dict CLOB := 'COMPOUND	back|woods|man	STEM	backwoodsman	noun';
BEGIN
  CTX_ANL.ADD_DICTIONARY('dict16','ENGLISH',dict);
END;

22. Compound из четырёх частей (EN)

DECLARE
  dict CLOB := 'COMPOUND	mother|in|law|book	STEM	motherinlawbook	noun';
BEGIN
  CTX_ANL.ADD_DICTIONARY('dict17','ENGLISH',dict);
END;

23. Русский compound (пример)

DECLARE
  dict CLOB := 'COMPOUND	свет|форум	STEM	светофор	noun';
BEGIN
  CTX_ANL.ADD_DICTIONARY('dict18','RUSSIAN',dict);
END;

24. Немецкий compound (Biergarten)

DECLARE
  dict CLOB := 'COMPOUND	Bier|Garten	STEM	Biergarten	noun';
BEGIN
  CTX_ANL.ADD_DICTIONARY('dict19','GERMAN',dict);
END;

25. Французский compound (chef-d’œuvre)

DECLARE
  dict CLOB := 'COMPOUND	chef|d’|œuvre	STEM	chef-d’œuvre	noun';
BEGIN
  CTX_ANL.ADD_DICTIONARY('dict20','FRENCH',dict);
END;

26. Переопределение STEM

DECLARE
  dict CLOB := 'STEM	running	verb';
BEGIN
  CTX_ANL.ADD_DICTIONARY('dict21','ENGLISH',dict);
END;

27. STEM с proper noun (FR)

DECLARE
  dict CLOB := 'STEM	Paris	nounProper';
BEGIN
  CTX_ANL.ADD_DICTIONARY('dict22','FRENCH',dict);
END;

28. STEM + признаки (RU)

DECLARE
  dict CLOB := 'STEM	Москва	nounProper	genderFeminine';
BEGIN
  CTX_ANL.ADD_DICTIONARY('dict23','RUSSIAN',dict);
END;

29. Несколько feature (EN)

DECLARE
  dict CLOB := 'STEM	student	noun	genderMasculine,declensionHard';
BEGIN
  CTX_ANL.ADD_DICTIONARY('dict24','ENGLISH',dict);
END;

30. Несколько строк словаря

DECLARE
  dict CLOB := 'STEM	dog	noun' || CHR(10) || 'STEM	cat	noun';
BEGIN
  CTX_ANL.ADD_DICTIONARY('dict25','ENGLISH',dict);
END;

Массовые операции (31–40)

31. Генерация словаря из таблицы (LISTAGG)

DECLARE
  dict CLOB;
BEGIN
  SELECT LISTAGG('STEM	' || word || '	noun', CHR(10)) INTO dict
  FROM my_words;
  CTX_ANL.ADD_DICTIONARY('dict26','ENGLISH',dict);
END;

32. Удаление словаря, сформированного из таблицы

DECLARE
  dict CLOB;
BEGIN
  SELECT LISTAGG('STEM	' || word || '	noun', CHR(10)) INTO dict
  FROM my_words;
  CTX_ANL.DROP_DICTIONARY('dict26','ENGLISH',dict);
END;

33. Добавление словаря и проверка представления

DECLARE
  dict CLOB := 'STEM	demo	noun';
BEGIN
  CTX_ANL.ADD_DICTIONARY('dict27','ENGLISH',dict);
END;

-- Проверка
SELECT * FROM CTX_USER_ANALYZER_DICTS;

34. Удаление словаря и проверка представления

DECLARE
  dict CLOB := 'STEM	demo	noun';
BEGIN
  CTX_ANL.DROP_DICTIONARY('dict27','ENGLISH',dict);
END;

-- Проверка
SELECT * FROM CTX_USER_ANALYZER_DICTS;

35. Добавление словаря перед созданием индекса

DECLARE
  dict CLOB := 'STEM	document	noun';
BEGIN
  CTX_ANL.ADD_DICTIONARY('dict28','ENGLISH',dict);
END;

CREATE INDEX idx_docs ON docs(text) INDEXTYPE IS CTXSYS.CONTEXT;

36. Удаление словаря перед перестроением индекса

DECLARE
  dict CLOB := 'STEM	document	noun';
BEGIN
  CTX_ANL.DROP_DICTIONARY('dict28','ENGLISH',dict);
END;

ALTER INDEX idx_docs REBUILD;

37. Логирование ошибок добавления словаря

DECLARE
  dict CLOB := 'WRONGFORMAT';
BEGIN
  CTX_ANL.ADD_DICTIONARY('dict29','ENGLISH',dict);
EXCEPTION
  WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE('Ошибка: ' || SQLERRM);
END;

38. Массовое добавление словарей в цикле

DECLARE
  v_words SYS.ODCIVARCHAR2LIST := SYS.ODCIVARCHAR2LIST('alpha','beta','gamma');
  dict CLOB;
BEGIN
  FOR i IN 1..v_words.COUNT LOOP
    dict := 'STEM	' || v_words(i) || '	noun';
    CTX_ANL.ADD_DICTIONARY('dict' || i,'ENGLISH',dict);
  END LOOP;
END;

39. Условное добавление (если нет в представлении)

DECLARE
  dict CLOB := 'STEM	test	noun';
  cnt NUMBER;
BEGIN
  SELECT COUNT(*) INTO cnt FROM CTX_USER_ANALYZER_DICTS WHERE DICT_NAME='dict30';
  IF cnt = 0 THEN
    CTX_ANL.ADD_DICTIONARY('dict30','ENGLISH',dict);
  END IF;
END;

40. Условное удаление (если найден в представлении)

DECLARE
  dict CLOB := 'STEM	test	noun';
  cnt NUMBER;
BEGIN
  SELECT COUNT(*) INTO cnt FROM CTX_USER_ANALYZER_DICTS WHERE DICT_NAME='dict30';
  IF cnt > 0 THEN
    CTX_ANL.DROP_DICTIONARY('dict30','ENGLISH',dict);
  END IF;
END;

Тестирование и сценарии (41–50)

41. Тест: есть ли токен после добавления

DECLARE
  dict CLOB := 'STEM	newword	noun';
BEGIN
  CTX_ANL.ADD_DICTIONARY('dict31','ENGLISH',dict);
END;

-- пример проверки (замени idx_docs на свой индекс):
SELECT token_text FROM dr$idx_docs$i WHERE token_text='newword';

42. Перестроение индекса

ALTER INDEX idx_docs REBUILD;

43. Русский глагол

DECLARE
  dict CLOB := 'STEM	читать	verb';
BEGIN
  CTX_ANL.ADD_DICTIONARY('dict32','RUSSIAN',dict);
END;

44. Немецкое сложное слово (Arbeitszeit)

DECLARE
  dict CLOB := 'COMPOUND	Arbeit|Zeit	STEM	Arbeitszeit	noun';
BEGIN
  CTX_ANL.ADD_DICTIONARY('dict33','GERMAN',dict);
END;

45. Удаление русского словаря

DECLARE
  dict CLOB := 'STEM	читать	verb';
BEGIN
  CTX_ANL.DROP_DICTIONARY('dict32','RUSSIAN',dict);
END;

46. Удаление немецкого словаря

DECLARE
  dict CLOB := 'COMPOUND	Arbeit|Zeit	STEM	Arbeitszeit	noun';
BEGIN
  CTX_ANL.DROP_DICTIONARY('dict33','GERMAN',dict);
END;

47. Валидация: намеренно некорректная строка

DECLARE
  dict CLOB := 'STEM	invalid';
BEGIN
  CTX_ANL.ADD_DICTIONARY('dict34','ENGLISH',dict);
END;

-- Ошибка выявится при CREATE/ALTER INDEX (DRG-13710)

48. Миграция: выгрузка словарей в другую схему

INSERT INTO other_schema.my_dicts
SELECT * FROM CTX_USER_ANALYZER_DICTS;

49. Очистка всех словарей пользователя

DECLARE
  CURSOR c IS SELECT DICT_NAME, LANGUAGE, DICTIONARY FROM CTX_USER_ANALYZER_DICTS;
BEGIN
  FOR rec IN c LOOP
    CTX_ANL.DROP_DICTIONARY(rec.DICT_NAME, rec.LANGUAGE, rec.DICTIONARY);
  END LOOP;
END;

50. Автоматическое добавление словаря (DBMS_SCHEDULER)

BEGIN
  DBMS_SCHEDULER.CREATE_JOB(
    job_name        => 'add_dict_job',
    job_type        => 'PLSQL_BLOCK',
    job_action      => 'DECLARE d CLOB := ''STEM	scheduler	noun''; BEGIN CTX_ANL.ADD_DICTIONARY(''dict35'',''ENGLISH'',d); END;',
    start_date      => SYSTIMESTAMP,
    repeat_interval => 'FREQ=DAILY;INTERVAL=1',
    enabled         => TRUE
  );
END;

Заключение

CTX_ANL расширяет возможности AUTO_LEXER в Oracle Text: добавление/удаление словарей,
поддержка сложных слов, морфологии и автоматизация. Примеры выше можно применять в реальных проектах.

Полезные ссылки


 

Понравилась статья? Поделиться с друзьями: