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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在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的电子邮件作为地址的一部分,因此doc将在其两侧都有一个句点。

即mail.doc.george@here.com

我不希望那些事件发生。我在单词的末尾用空格试了它,它忽略了空格。我把它们放在我创建的搜索表中,如上所示,它仍然忽略了空格。有什么建议?

谢谢!!

答案

这是两个建议。

简单,低效的方法是使用除CONTAINS之外的东西。为了正确起见,上下文索引非常棘手。因此,您可以执行以下操作,而不是最后一行:

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

我认为这应该有效,但可能会很慢。这是你使用索引的时候。但Oracle Text索引比普通索引更复杂。 This old doc explains标点字符(在索引参数中定义)未编入索引,因为Oracle Text的要点是索引字。如果要将特殊字符作为单词的一部分编入索引,则需要将其添加到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

以上是关于在CLOB中搜索列表/表中的单词的主要内容,如果未能解决你的问题,请参考以下文章

在另一个表中搜索整个单词的表,如果找到则从结果中排除

给定一个文档,选择一个相关的片段

在 dart 中搜索列表和列表中的剩余单词

使用LIKE或IN表达式中的搜索模式列表

使用 C++ 反转句子中的每个单词需要对我的代码片段进行代码优化

搜索包含列表中的单词并具有特定文件扩展名的文件名