5

簡単な質問: Solr へのクエリをインターセプトし、ビジネス ロジックによって提供されるいくつかの追加のフィルタリング パラメータを挿入する方法 (Java) を探しています。どのような構造を使用すればよいですか?

コンテキスト: まず最初に、少し自白します: 私は Solr に関して初心者です。私にとっては、サーバーをセットアップし、スキーマを定義し、機能的なインデックスマネージャーをコーディングし、その後実際にサーバーが正しい結果を返すのを確認しました-まさに意図したとおりです! -それ自体はすでに多くの成果を上げていました。わーい!

しかし、私は現在、それ以上のものが必要なエンタープライズ プロジェクトに取り組んでいます。大まかに言えば、返されるドキュメントはユーザーのアクセス許可レベルに従って自動的にフィルター処理されるため、solr インスタンスはまったく同じ requestHandler を介して数千のユーザーによって照会されます。たとえば、ユーザー A とスーパーユーザー B の両方がまったく同じ検索パラメーター (まったく同じ URL であっても) を試行した場合、ユーザー B はユーザー A のすべてのファイルを取得し、さらにいくつかのファイルを取得します。これを実現するために、ドキュメントは必要なアクセス許可レベル情報で既にインデックス化されています。

さて、これを念頭に置いて、新人開発者向けの Solr の広範なドキュメントを利用して、SolrQueryRequest に必要な追加パラメーターを挿入するために、handleRequest 関数をオーバーライドする単純なカスタム requestHandler を考え出そうとしました。サーバーは私の小さな操作を無礼に無視して、QueryResponseにまったく違いが見られないことを除いて、すべてがうまくいきます。これが最善のアプローチである場合、ヒント天気なしで数日間Webを検索した後、最終的にここに来て、ここStackOverflowの素晴らしい人々を悩ませることにしました。

つまり、要するに、私の質問は次のとおりです。

  • これは正しいアプローチですか?他の選択肢はありますか?Solr の概念の一部はすでに理解できていますが、確かに不足しているものは多く、何かが欠けている可能性は十分にあります。

  • その場合、クエリ パラメータを変更した後、QueryResponse を強制的に更新するために何かする必要がありますか? 私が知る限り、これらは単に http リクエストをカプセル化しているだけであり、変更が行われた後にサーバーにクエリを送信するものを盗聴することはできません。

事前に感謝し、長い投稿を申し訳ありません!

アップデート

多くのAPIを読み、特に多くの試行錯誤を重ねた後、機能的なソリューションを得ることができました。しかし、私はまだ Solr の内部構造の多くを理解できていません。意のままにバッシュしてください。

ソリューションの関連部分は、オーバーライドされた handleRequestBody によって呼び出されるこの関数です。

private void SearchDocumentsTypeII(SolrDocumentList results,
        SolrIndexSearcher searcher, String q, 
        UserPermissions up, int ndocs, SolrQueryRequest req,
        Map<String, SchemaField> fields, Set<Integer> alreadyFound)
        throws IOException, ParseException {


         BooleanQuery bq = new BooleanQuery();
         String permLvl = "PermissionLevel:" + up.getPermissionLevel();
         QParser parser = QParser.getParser(permLvl, null, req);
         bq.add(parser.getQuery(), Occur.MUST);

         Filter filter = CachingWrapperFilter(new QueryWrapperFilter(bq));   

         QueryParser qp = new QueryParser(q, new StandardAnalyzer());
         Query query =  qp.parse(q);                        

         append (results, searcher.search(
          query, filter, 50).scoreDocs,
          alreadyFound, fields, new HashMap<String,Object>(), 0,
          searcher.getReader(), true);

}

基本的に、検索クエリはまったく変更されず、代わりにユーザーの PermissionLevel を含むフィルターが適用されます。それでも、次の代替案が機能しないのはなぜですか? 検索クエリは、標準の requestHandler に適用すると完全に機能しますが、この場合、どのドキュメントにもヒットしません。

private void SearchDocumentsTypeII(SolrDocumentList results,
        SolrIndexSearcher searcher, String q, 
        UserPermissions up, int ndocs, SolrQueryRequest req,
        Map<String, SchemaField> fields, Set<Integer> alreadyFound)
        throws IOException, ParseException {

         String qFiltered = q + " AND " + "PermissionLevel:" + up.getPermissionLevel();                              

         QueryParser qp = new QueryParser(qFiltered, new StandardAnalyzer());
         Query query =  qp.parse(qFiltered);                        

         append (results, searcher.search(
          query, null, 50).scoreDocs,
          alreadyFound, fields, new HashMap<String,Object>(), 0,
          searcher.getReader(), true);

}

4

3 に答える 3

2

朗報です。これを行うためにコードを記述する必要はありません。Solr を適切に構成するだけで済みます。スーパーユーザーは標準のリクエストハンドラーをヒットし、通常のユーザーは、強制したいフィルタークエリを使用して不変条件solr.StandardRequestHandlerで構成された別のリクエストハンドラー (これも )をヒットします。

http://wiki.apache.org/solr/SolrRequestHandlerも参照してください。

于 2011-05-31T03:43:16.757 に答える
1

しかたがない。前に述べたように、私のために働いた答え。コメントまたはbashしてください!

   private void SearchDocumentsTypeII(SolrDocumentList results,
            SolrIndexSearcher searcher, String q, 
            UserPermissions up, int ndocs, SolrQueryRequest req,
            Map<String, SchemaField> fields, Set<Integer> alreadyFound)
            throws IOException, ParseException {


             BooleanQuery bq = new BooleanQuery();
             String permLvl = "PermissionLevel:" + up.getPermissionLevel();
             QParser parser = QParser.getParser(permLvl, null, req);
             bq.add(parser.getQuery(), Occur.MUST);

             Filter filter = CachingWrapperFilter(new QueryWrapperFilter(bq));   

             QueryParser qp = new QueryParser(q, new StandardAnalyzer());
             Query query =  qp.parse(q);                        

             append (results, searcher.search(
              query, filter, 50).scoreDocs,
              alreadyFound, fields, new HashMap<String,Object>(), 0,
              searcher.getReader(), true);
        }
于 2011-06-02T16:29:06.233 に答える
0

このsolrwikiページを見てください。最初にApacheManifoldFrameworkの使用を検討する必要があります。ニーズに合わない場合は、独自のrequestHandlerを記述してください。

于 2011-05-31T14:13:09.547 に答える