2

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

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

但是,出现了一个关键问题:Oracle 不会允许“in”子句中的项目数组中的项目超过 1000 个(大交易,因为我发现的对象列表经常 > 1000,通常在 50- 200k 项)

我尝试使用“split”函数解决此问题,该函数将采用逗号分隔的字符串并将它们分解为数组项,但随后我使用 SQL(PL/SQL是 32k 个字符,但在某些情况下,对于 80,000+ 个结果来说,它仍然太有限了)

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

我已经尝试为 1000 项限制(又名:id in (1...1000 or (id in (1001....2000) 或 id in (2001....3000) )) - 这有效,但速度慢。

我在想我应该将 Solr 客户端 JAR 加载到 Oracle 中,并用 Java 编写一个 Oracle 函数,该函数将调用 solr 并将结果作为列表返回,这样我就可以执行以下操作:

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

事实证明这非常困难,我什至不确定这是否可能。

我不能做的事情:

  • 在 Solr 中存储完整数据(安全性 + 存储限制)
  • 用户 Solr 作为分页和排序的控制器(这就是我从数据库中获取数据的原因)

因此,我必须设计一种混合方法,让 Solr 真正充当 Oracle 的全文搜索提供程序。帮助!有没有人遇到过这个?

4

4 回答 4

2

看看这个: http ://demo.scotas.com/search-sqlconsole.php

该产品似乎完全可以满足您的需求。

干杯

于 2013-06-07T20:12:44.937 回答
1

我不是 Solr 专家,但我假设您可以将 Solr 查询结果放入 Java 集合中。一旦你有了它,你应该能够使用 JDBC 来使用该集合。这避免了 1000 个文字项的限制,因为您的 IN 列表将是查询的结果,而不是文字值的列表。

Dominic Brooks 有一个将对象集合与 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)))
于 2010-10-01T18:16:39.230 回答
0

您可以使用术语过滤器(类似于 RangeFilter,但项目不必按顺序排列),而不是使用长的 BooleanQuery。

像这样(首先用条款填写您的条款过滤器):

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 文档): http ://lucene.apache.org/solr/api/org/apache/solr/search/SolrIndexSearcher.html

于 2010-10-04T10:42:44.230 回答
0

想到了两个解决方案。

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

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

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

于 2011-01-14T17:47:20.777 回答