【问题标题】:Context Indexes To include Special Characters包含特殊字符的上下文索引
【发布时间】:2017-09-06 03:31:40
【问题描述】:

我有以下结构的表

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。

【问题讨论】:

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


    【解决方案1】:

    使用\{...}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;
    

    问题

    默认情况下,逗号被视为累加运算符并返回所有四行,因为它们都有“aaron”或“lord”。

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

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

    转义累加器将阻止 ORing 并排除“aaron”和“lord”。我假设真正的查询使用绑定变量并且没有硬编码,这就是为什么下面的查询使用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 函数和条件。

    【讨论】:

    • 我用过这个案例select description from mytable where contains(description, '{' || 'aaron,lord' || '}') > 0; 它显示的结果也具有价值 aaron lord。请告诉我如何避免这种情况?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-25
    • 2021-02-09
    • 1970-01-01
    • 2011-10-24
    • 1970-01-01
    • 2021-07-14
    • 1970-01-01
    相关资源
    最近更新 更多