Oracle 文本短语错误 (DRG-50920)。查询解析和SYN函数
Oracle text phrase error (DRG-50920). Query parsing and SYN function
我刚开始使用 Oracle Text,已经修改了文档,但我真的很难找到解决方案。
目前正在使用渐进式放松,但我不断收到以下错误:
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.
我有两个问题:
如何对标签中的查询进行转义?也许 {} ?如果不转义,当我输入 COCA COLA 0,5L
.
之类的内容时,它将无法工作
另一方面,当查询包含在转义字符 ({ }
) 中并且我尝试使用 "EL K"
时,它会引发相同的异常。 "EL"
是同义词库的一部分。
代码
Table 和索引创建:
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({something}, thes) 在多个单词被空格分隔时不起作用。
所以这些词之间必须有一个运算符。
如果我从文本查询中删除以下行,查询将使用 SYN:
<seq><rewrite>transform((TOKENS, "FUZZY(SYN({", "}, inv_thes), 70, 10, weight)", " "))</rewrite></seq>
但我仍然不确定可能是什么原因。
我的解决方案是使用自定义变通函数而不是 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;
我刚开始使用 Oracle Text,已经修改了文档,但我真的很难找到解决方案。 目前正在使用渐进式放松,但我不断收到以下错误:
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.
我有两个问题:
如何对标签中的查询进行转义?也许 {} ?如果不转义,当我输入
COCA COLA 0,5L
. 之类的内容时,它将无法工作
另一方面,当查询包含在转义字符 (
{ }
) 中并且我尝试使用"EL K"
时,它会引发相同的异常。"EL"
是同义词库的一部分。
代码
Table 和索引创建:
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({something}, thes) 在多个单词被空格分隔时不起作用。
所以这些词之间必须有一个运算符。
如果我从文本查询中删除以下行,查询将使用 SYN:
<seq><rewrite>transform((TOKENS, "FUZZY(SYN({", "}, inv_thes), 70, 10, weight)", " "))</rewrite></seq>
但我仍然不确定可能是什么原因。
我的解决方案是使用自定义变通函数而不是 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;