【问题标题】:Oracle: how to do full text searches on an XMLType?Oracle:如何对 XMLType 进行全文搜索?
【发布时间】:2011-09-14 08:37:27
【问题描述】:
我有一个在 Oracle 表中存储 XML 为 XMLType 的应用程序。我想对该数据进行全文搜索。 Full-Text Search Over XML Data 中的 Oracle 文档建议使用 contains SQL 函数,该函数需要使用 context 索引对数据进行索引。问题是context 索引似乎是asynchronous,这不适合我需要能够在添加数据后立即搜索数据的用例。
我可以使该索引以某种方式同步吗?如果不是,我应该使用什么其他技术对XMLType 进行全文搜索?
【问题讨论】:
标签:
oracle
full-text-search
xmltype
【解决方案1】:
它不能成为事务性的(即它不会更新索引,以便事务中的后续语句可以看到更改)。你能做的最好的就是让它在提交时更新 (SYNC ON COMMIT),如下所示:
create index your_table_x
on your_table(your_column)
indextype is ctxsys.context
parameters ('sync (on commit)');
文本索引是复杂的东西,如果您能够实现符合事务/ACID 的文本索引,我会感到惊讶(即事务 A 插入文档并在该事务的索引中显示这些文档,而事务 B 直到提交)。
【解决方案2】:
您可以在cron-like kind of way 中定期更新索引。更糟糕的是,您可以在每次更新表后更新索引,使用sync_index 构建索引。例如:EXEC CTX_DDL.SYNC_INDEX('your_index'); 我不是这种技术的忠实粉丝,因为它引入了复杂性。除了类似 cron 的方面,您还必须处理索引碎片,这可能需要您不时进行完整更新。 更新:您可以在提交时更新它,而不是定期更新索引,如 suggested by Gary,这正是您要寻找的。p>
-
您可以对 XML 文档进行简单的文本搜索,就像在文本编辑器中对 XML 执行 ctrl-f 一样。在许多情况下,这不会给您预期的结果,因为用户并不关心他们正在搜索的字符串是否恰好在元素名称、属性名称或命名空间中使用。但是,如果这个方法对你有用,那就去吧:它简单而且相当快。例如:
select count(*) from your_table d
where lower(d.your_column.getClobVal()) like '%gaga%';
-
在where 子句中使用existsNode(),如下例所示。这有两个潜在的问题。首先,如果没有适当的索引,这比方法 #2 慢,在我的测试中大约是 2 倍,而且我不确定如何为该查询使用的非结构化数据创建索引。其次,您将进行区分大小写的搜索,这通常不是您想要的。而且你不能只调用 XPath 的lower-case(),因为 Oracle 只支持 XPath 1.0。
select * from your_table
where existsNode(your_column, '//text()[contains(., "gaga")]') = 1;