上下文索引包括特殊字符

时间:2017-04-10 22:59:37

标签: database oracle indexing full-text-indexing database-indexes

我有以下结构的表

mytable(id number, name varchar2(100), department varchar2(100), description varchar2(100));

并在描述栏

上创建了上下文索引

create index myindex on mytable(description) indextype IS CTXSYS.CONTEXT parameters(lexer mylex);

description列包含逗号分隔值,当我执行以下搜索时,它会进行OR搜索。

select * from mytable where contains(description,'aaron,lord')>0;

它将描述列的结果作为aaron或lord。

1 个答案:

答案 0 :(得分:0)

使用\{...}escape accumulate operators

示例架构

--drop table mytable;

create table mytable(id number,
name varchar2(100),
department varchar2(100),
description varchar2(100));

insert into mytable values(1, 'A', 'A', 'aaron,lord');
insert into mytable values(2, 'B', 'B', 'aaron');
insert into mytable values(3, 'C', 'C', 'lord');
commit;

create index myindex on mytable(description)
indextype IS CTXSYS.CONTEXT;

<强>问题

默认情况下,逗号被视为累积运算符并返回所有四行,因为它们都有&#34; aaron&#34;或者&#34;领主&#34;。

select description from mytable where contains(description,'aaron,lord')>0;

DESCRIPTION
-----------
aaron,lord
aaron
lord
aaron lord

解决方案第1部分 - 转义逗号

转储累加器将阻止ORing并排除&#34; aaron&#34;和&#34;领主&#34;。我假设真正的查询使用绑定变量而不是硬编码,这就是下面的查询使用REPLACE||而不是简单地修改字符串的原因。

select description from mytable where contains(description, replace('aaron,lord', ',', '\,')) > 0;
select description from mytable where contains(description, '{' || 'aaron,lord' || '}') > 0;

DESCRIPTION
-----------
aaron,lord
aaron lord

解决方案第2部分 - 为printjoin添加逗号

drop index myindex;

begin
    ctx_ddl.create_preference('mylex', 'BASIC_LEXER');
    ctx_ddl.set_attribute('mylex', 'printjoins', ',');
end;
/

create index myindex on mytable(description)
indextype IS CTXSYS.CONTEXT
parameters ('LEXER mylex');

现在只返回一行。

select description from mytable where contains(description, replace('aaron,lord', ',', '\,')) > 0;
select description from mytable where contains(description, '{' || 'aaron,lord' || '}') > 0;

DESCRIPTION
-----------
aaron,lord

但结果变得如此具体,我想知道避免CONTAINS并使用常规SQL函数和条件是否更好。