Oracle ошибка текстовой фразы (DRG-50920). Парсинг запросов и функция SYN - PullRequest
2 голосов
/ 18 апреля 2020

Я только начал работать с Oracle Текст, уже красные документы, но я действительно изо всех сил, чтобы найти решение. В настоящее время я использую прогрессивную релаксацию, но постоянно получаю следующую ошибку:

ORA-29902: error in executing ODCIIndexStart() routine
ORA-20000: Oracle Text error:
DRG-50920: part of phrase not itself a phrase or equivalence  
29902. 00000 -  "error in executing ODCIIndexStart() routine"
*Cause:    The execution of ODCIIndexStart routine caused an error.
*Action:   Examine the error messages produced by the indextype code and
           take appropriate action.

У меня есть два вопроса:

  1. Как избежать запроса в теге? Может быть {} ? Без экранирования это не будет работать, когда я наберу что-то вроде COCA COLA 0,5L.

  2. С другой стороны, когда запрос заключен в escape-символы ({ }), и я пытаюсь с "EL K" оно вызывает то же исключение. "EL" является частью тезауруса.

Код

Создание таблицы и индекса:

CREATE TABLE "DAVID"."INVENTAR_DEV" (
    "ID"   VARCHAR2(16 BYTE)
        NOT NULL ENABLE,
    "NAME"          VARCHAR2(255 BYTE)
        NOT NULL ENABLE
);

CREATE INDEX "DAVID"."INV_DEV_NAME_IDX" ON
    "DAVID"."INVENTAR_DEV" (
        "NAME"
    )
        INDEXTYPE IS "CTXSYS"."CONTEXT" PARAMETERS ( 'DATASTORE CTXSYS.DEFAULT_DATASTORE FILTER CTXSYS.NULL_FILTER LEXER INVENTAR_DEV_LEXER WORDLIST  INV_DEV_WORDLIST STOPLIST CTXSYS.EMPTY_STOPLIST'
        );

SELECT, который я использую:

 SELECT /*+ FIRST_ROWS(150) */
                  XMLELEMENT("object",
                    XMLForest(i.id "id", 
                              i.name "name"
                    ).getStringVal()
            FROM david.inv_dev i
                WHERE contains(i.name, 
            '<query> 
                <textquery grammar="context"> {EL KOS}
                    <progression>
                        <seq><rewrite>transform((TOKENS, "FUZZY(SYN({", "}, inv_thes), 70, 10, weight)", " "))</rewrite></seq>
                        <seq><rewrite>transform((TOKENS, "FUZZY(SYN({", "}, inv_thes), 70, 10, weight)", " AND "))</rewrite></seq>
                    </progression>
                </textquery>
                <score datatype="FLOAT" algorithm="DEFAULT"/>
                <order>
                    <orderkey> Score DESC </orderkey>
                </order>
            </query>', 1) > 0;

Также создал мой собственный WORDLIST и LEXER:


BEGIN
   ctx_ddl.create_preference('INVENTAR_DEV_LEXER','BASIC_LEXER');

   ctx_ddl.set_attribute('INVENTAR_DEV_LEXER', 'numgroup',',');

   ctx_ddl.set_attribute('INVENTAR_DEV_LEXER', 'numjoin','.');

   ctx_ddl.set_attribute('INVENTAR_DEV_LEXER', 'skipjoins','.-_%:;/,()?!*+');

   ctx_ddl.create_preference('INV_DEV_WORDLIST', 'BASIC_WORDLIST');

   ctx_ddl.set_attribute('INV_DEV_WORDLIST','FUZZY_MATCH','GENERIC');
   ctx_ddl.set_attribute('INV_DEV_WORDLIST','FUZZY_SCORE','70');
   ctx_ddl.set_attribute('INV_DEV_WORDLIST','FUZZY_NUMRESULTS','10');

   ctx_ddl.set_attribute('INV_DEV_WORDLIST','SUBSTRING_INDEX','FALSE');

   ctx_ddl.set_attribute('INV_DEV_WORDLIST','STEMMER','NULL');

   ctx_ddl.set_attribute('INV_DEV_WORDLIST','PREFIX_INDEX','TRUE');
   ctx_ddl.set_attribute('INV_DEV_WORDLIST','PREFIX_MIN_LENGTH',3);
   ctx_ddl.set_attribute('INV_DEV_WORDLIST','PREFIX_MAX_LENGTH',7);

   Ctx_thes.create_thesaurus('inv_thes', FALSE); -- NAMEE, CASE-SENSITIVE
   CTX_THES.CREATE_RELATION('inv_thes','el','SYN','elektro');

END;

Обновление

Я понял, что SYN ({что-то}, thes) не работает, когда есть несколько слов, разделенных пробелами.

Таким образом, между этими словами должен быть оператор.

Запрос работает с SYN, если я удалю следующую строку из текстового запроса:

<seq><rewrite>transform((TOKENS, "FUZZY(SYN({", "}, inv_thes), 70, 10, weight)", " "))</rewrite></seq>

Но я ' Я до сих пор не уверен, в чем может быть причина.

1 Ответ

0 голосов
/ 21 апреля 2020

Моим решением проблемы было использование пользовательской функции обхода вместо SYN и пользовательской функции анализа запроса.

Функция обхода для SYN:

  FUNCTION f_synonyms(p_word IN VARCHAR2) 
  RETURN VARCHAR2
  AS
    CURSOR c_synonyms (p_word IN VARCHAR2)
    IS
        SELECT REPLACE(CTX_THES.SYN(p_word, g_thesaurus_name), '|','=')
        FROM SYS.dual;
    v_retVal VARCHAR(255);  
  BEGIN
    OPEN  c_synonyms(p_word);
    FETCH c_synonyms INTO v_retVal;
    CLOSE c_synonyms;

    RETURN v_retVal;
  END;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...