我有一个将XML存储在Oracle表中的应用程序XMLType
。我想对该数据进行全文搜索。 Full-Text Search Over XML Data中的Oracle文档建议使用contains
SQL函数,该函数要求使用context
索引对数据建立索引。麻烦的是,context
索引似乎是asynchronous,这不符合我需要能够在添加数据后立即搜索数据的用例。
我可以以某种方式使该索引同步吗?如果没有,我应该使用什么其他技术在XMLType
上进行全文搜索?
答案 0 :(得分:4)
它不能成为事务性的(即它不会更新索引,以便更改对事务中的后续语句可见)。您可以做的最好的事情是在提交(SYNC ON COMMIT
)上进行更新,如:
create index your_table_x
on your_table(your_column)
indextype is ctxsys.context
parameters ('sync (on commit)');
文本索引是复杂的事情,如果你能够实现一个事务性/ ACID兼容的文本索引,我会感到惊讶(也就是说,事务A插入文档并在那个事务的索引中显示那些,并且直到事务B不可见提交)。
答案 1 :(得分:3)
您可以定期更新索引,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%';
在existsNode()
子句中使用where
,如下例所示。这有两个潜在的问题。首先,没有适当的索引,这比方法#2慢,在我的测试中约为2,我不知道如何在此查询将使用的非结构化数据上创建索引。其次,您将进行区分大小写的搜索,这通常不是您想要的。而且你不能只调用XPath的lower-case()
,因为Oracle只支持XPath 1.0。
select * from your_table
where existsNode(your_column, '//text()[contains(., "gaga")]') = 1;