我有一个包含所有“数据”的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真的像Oracle的全文搜索提供程序一样。救命!有没有人遇到过这个?
答案 0 :(得分:2)
答案 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特定的扩展,我认为你应该获得非常合理的性能。