2

すべての「データ」を含むOracleデータベースと、このすべてのデータにインデックスが付けられたSolrインデックスがあります。理想的には、次のようなクエリを実行できるようにしたいと考えています。

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

ただし、重要な問題が 1 つあります。Oracle は、「in」句のアイテムの配列に 1000 を超えるアイテムを許可しません (私が見つけるオブジェクトのリストは非常に頻繁に 1000 を超え、通常は約 50- 20万アイテム)

コンマ区切りの値の文字列を取り、それらを配列項目に分割する「分割」関数を使用してこれを回避しようとしましたが、SQL (PL/SQLは 32k 文字ですが、場合によっては 80,000 以上の結果を得るにはまだ制限が多すぎます)

WHERE IN (....) を使用してパフォーマンスの問題も発生しています。参照されているフィールドがインデックス付きフィールドであっても、これによりクエリが非常に遅くなると言われています。

1000 項目の制限 (別名: id in (1...1000 または (id in (1001....2000)) または id in (2001....3000)) に対して再帰的な「OR」を作成しようとしました)) - これは機能しますが、非常に遅いです。

Solr クライアント JAR を Oracle にロードし、solr を呼び出して結果をパイプラインでリストに戻す Oracle 関数を Java で記述して、次のようなことができるようにする必要があると考えています。

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

これは非常に難しいことが証明されており、それが可能かどうかさえわかりません。

私ができないこと:

  • 完全なデータを Solr に保存する (セキュリティ + ストレージ制限)
  • ページネーションと順序付けのコントローラーとしてSolrを使用します(これが、DBからデータを取得している理由です)

そのため、Solr が実際に Oracle の全文検索プロバイダーのように機能するハイブリッド アプローチを考案する必要があります。ヘルプ!誰かがこれに直面しましたか?

4

4 に答える 4

2

これをチェックしてください: http://demo.scotas.com/search-sqlconsole.php

この製品は、まさにあなたが必要としているものを実行しているようです。

乾杯

于 2013-06-07T20:12:44.937 に答える
1

私は Solr の専門家ではありませんが、Solr クエリの結果を Java コレクションに取得できると思います。それができたら、そのコレクションを JDBC で使用できるはずです。IN リストはリテラル値のリストではなくクエリの結果になるため、1000 個のリテラル項目の制限を回避できます。

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

2つの解決策が思い浮かびます。

まず、JDBCに対するOracle固有のJava拡張機能の使用を検討します。これらを使用すると、実際の配列/リストを引数として渡すことができます。ストアドプロシージャを作成する必要があるかもしれませんが(これを行わなければならなかったのでしばらく経ちました)、これが焦点を絞ったユースケースである場合は、過度に負担になることはありません。

次に、1000個のオブジェクト制限などの境界にまだ遭遇している場合は、Solrにクエリを実行するときに「行」設定を使用し、固有のページネーション機能を利用することを検討してください。

ストアドプロシージャでこのバルクフェッチメソッドを使用して、Solrに配置する必要のある大量のデータをフェッチしました。DBAを巻き込みます。優れた拡張機能があり、Oracle固有の拡張機能を使用している場合は、非常に妥当なパフォーマンスを達成する必要があると思います。

于 2011-01-14T17:47:20.777 に答える
0

長い BooleanQuery を使用する代わりに、TermsFilter を使用できます (RangeFilter と同様に機能しますが、項目が順番に並んでいる必要はありません)。

このように (最初に 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 ドキュメントを参照してください): http://lucene.apache.org/solr/api/org/apache/solr/search/SolrIndexSearcher.html

于 2010-10-04T10:42:44.230 に答える