在CLOB中搜索列表/表中的单词

时间:2018-09-27 22:10:56

标签: oracle select contains clob

我有一个带有Clob列的大表(+ 100,000行),我需要从中搜索特定时间范围内的特定单词。

{select id, clob_field,  dbms_lob.instr(clob_field, '.doc',1,1) as doc,  --ideally want .doc
      dbms_lob.instr(clob_field, '.docx',1,1) as docx, --ideally want .docx
      dbms_lob.instr(clob_field, '.DOC',1,1) as DOC,  --ideally want .DOC
      dbms_lob.instr(clob_field, '.DOCX',1,1) as DOCX  --ideally want .DOCX
 from clob_table, search_words s
 where (to_char(date_entered, 'DD-MON-YYYY') 
      between to_date('01-SEP-2018') and to_date('30-SEP-2018'))
 AND (contains(clob_field, s.words )>0)  ;}

这组单词是“ .doc”,“。DOC”,“。docx”和“ .docx”。当我使用 CONTAINS()似乎忽略了点,因此为我提供了很多行,但其中没有文档扩展名。它查找以.doc作为地址一部分的电子邮件,因此该文档的两边都有一个句点。

即mail.doc.george@here.com

我不希望发生这些事情。我试过在单词的末尾加一个空格,但它忽略了空格。我将它们放在我创建的搜索表中,如上所示,但它仍然忽略空格。有什么建议么?

谢谢!

1 个答案:

答案 0 :(得分:1)

这里有两个建议。

简单,低效的方法是使用CONTAINS之外的其他东西。众所周知,上下文索引很难正确处理。因此,您可以代替最后一行:

AND regexp_instr(clob_field, '\.docx', 1,1,0,'i') > 0

我认为应该可以,但是可能会很慢。您将在何时使用索引。但是Oracle Text索引比普通索引更复杂。 This old doc explains {@索引参数中定义的标点符号未编入索引,因为Oracle文本的重点是索引 words 。如果希望将特殊字符作为单词的一部分编制索引,则需要将其添加到 printjoin 字符集中。 This doc explains how,但我将其粘贴到此处。您需要删除现有的CONTEXT索引,并使用以下首选项重新创建它:

begin
ctx_ddl.create_preference('mylex', 'BASIC_LEXER');
ctx_ddl.set_attribute('mylex', 'printjoins', '._-'); -- periods, underscores, dashes can be parts of words
end;
/

CREATE INDEX myindex on clob_table(clob_field) INDEXTYPE IS CTXSYS.CONTEXT
  parameters ('LEXER mylex');

请记住,默认情况下,CONTEXT索引不区分大小写;我想这就是您想要的,但是仅供参考,您可以通过在词法分析器上将'mixed_case'属性设置为'Y'来更改它,就在上面的上方设置printjoins属性的位置。

似乎您正在尝试搜索以.docx结尾的单词,但是CONTAINS不是INSTR-默认情况下,它匹配整个单词,而不是字符串。您可能希望修改查询以执行AND contains(clob_field, '%.docx')>0