将Solr作为索引与Oracle作为存储数据库集成的最佳方法是什么?

时间:2010-10-01 17:58:00

标签: oracle solr integration limits

我有一个包含所有“数据”的Oracle数据库,以及一个索引所有这些数据的Solr索引。理想情况下,我希望能够运行这样的查询:

select * from data_table where id in([solr query results for'search string']);

然而,出现了一个关键问题: Oracle将不允许在“in”子句中的项目数组中包含超过1000个项目(BIG DEAL,因为我找到的对象列表通常> 1000,通常约为50-200k项目)

我尝试使用“split”函数解决这个问题,该函数将采用逗号分隔值的字符串,并将它们分解为数组项,但随后我使用SQL命中函数参数的4000字符串限制( PL / SQL是32k字符,但在某些情况下它仍然限制80,000+结果)

我也使用WHERE IN(....)来解决性能问题,我被告知这会导致查询非常慢,即使引用的字段是索引字段?

我已尝试为1000项限制制作递归“OR”(又名:id in(1 ... 1000或(id in(1001 .... 2000)或id in(2001 ...) .3000))) - 这是有效的,但非常慢。

我在想我应该将Solr Client JAR加载到Oracle中,并在Java中编写一个Oracle函数,它将调用solr并将结果作为列表返回管道,以便我可以执行以下操作:

select * from data_table where id in(select * from table(runSolrQuery('my query text')));

这证明非常困难,我不确定它是否可能。

我不能做的事情:

  • 在Solr中存储完整数据(security + 存储限制)
  • 用户Solr as 分页和排序控制器 (这就是我从中获取数据的原因 DB)

所以我必须做一个混合方法,Solr真的像Oracle的全文搜索提供程序一样。救命!有没有人遇到过这个?

4 个答案:

答案 0 :(得分:2)

检查一下: http://demo.scotas.com/search-sqlconsole.php

这款产品似乎完全符合您的需求。

欢呼声

答案 1 :(得分:1)

我不是Solr专家,但我认为您可以将Solr查询结果放入Java集合中。完成后,您应该能够将该集合与JDBC一起使用。这避免了1000个文字项的限制,因为您的IN列表将是查询的结果,而不是文字值的列表。

多米尼克布鲁克斯有一个using object collections with JDBC的例子。你会做类似

的事情

在Oracle中创建几种类型

CREATE TYPE data_table_id_typ AS OBJECT (
  id NUMBER
);

CREATE TYPE data_table_id_arr AS TABLE OF data_table_id_typ;

在Java中,您可以创建一个适当的STRUCT数组,从Solr填充此数组,然后将其绑定到SQL语句

SELECT *
  FROM data_table
 WHERE id IN (SELECT * FROM TABLE( CAST (? AS data_table_id_arr)))

答案 2 :(得分:0)

您可以使用TermsFilter(与RangeFilter类似,但不必使用长的BooleanQuery,而不是使用长的BooleanQuery。)

像这样(首先用条款填写你的TermsFilter):

TermsFilter termsFilter = new TermsFilter();

        // Loop through terms and add them to filter
        Term term = new Term("<field-name>", "<query>");
        termsFilter.addTerm(term);

然后像这样搜索索引:

DocList parentsList = null;
parentsList = searcher.getDocList(new MatchAllDocsQuery(),  searcher.convertFilter(termsFilter), null, 0, 1000);

搜索者是SolrIndexSearcher(有关getDocList方法的更多信息,请参阅java doc): http://lucene.apache.org/solr/api/org/apache/solr/search/SolrIndexSearcher.html

答案 3 :(得分:0)

我想到了两种解决方案。

首先,研究如何使用Oracle特定的Java扩展来实现JDBC。它们允许您传入一个实际的数组/列表作为参数。你可能需要创建一个存储过程(它已经有一段时间了,因为我必须这样做),但如果这是一个集中的用例,它不应该过于繁琐。

其次,如果您仍然遇到1000个对象限制的边界,请在查询Solr时考虑使用“rows”设置并利用其固有的分页功能。

我已经将这种批量提取方法与存储过程一起用于获取需要放入Solr的大量数据。让您的DBA参与进来。如果你有一个好的,并使用Oracle特定的扩展,我认为你应该获得非常合理的性能。