oracle-databaseplsqloracle-text

Oracle text phrase error (DRG-50920). Query parsing and SYN function


I just started working with Oracle Text, already red the docs but I really struggle to find a solution. Currently using with progressive relaxation but I keep getting the following error:

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.

I have two questions:

  1. How to escape the query in the tag? Maybe {} ? Without escaping it won't work when I type something like COCA COLA 0,5L.

  2. On the other hand, when the query is enclosed in the escape chars ({ }) and I try with "EL K" it thorws the same exception. "EL" is part of a thesaurus.

Code

Table and index creation:

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'
        );

The SELECT which I'm using:

 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;

Also created my own WORDLIST and 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;

Update

I realized that SYN({something}, thes) doesn't work when there are multiple words devided by spaces.

So there must be an operator between those words.

The query works with the SYN if I remove the following line from the textquery:

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

But I'm still not sure what could be the reason.


Solution

  • My solution to the problem was to use a custom workaround function instead of SYN and a custom query parsing function.

    The workaround function for 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;