Solr Custom RequestHandler - injecting query parameters

让人想犯罪 __ 提交于 2019-12-06 06:11:30

问题


Short question: I'm looking for a way (java) to intercept a query to Solr and inject a few extra filtering parameters provided by my business logic. What structures should I use?

Context: First of all, a little confession: I'm such a rookie regarding Solr. For me, setting up a server, defining a schema, coding a functional indexmanager and afterwards actually seeing the server returning the right results - exactly as intended! - was already much of an achievement for itself. Yay me!

However I'm currently working in an enterprise project that requires a little more than that. Roughly speaking, the solr instance is to be queried by several thousands of users through the very same requestHandler, being that the documents returned are automatically filtered according to a user's permission level. For example, if both the user A and the super-user B tried the very same search parameters (even the very same url), the user B would get all of user A's files and then some more. In order to accomplish this the documents are already indexed with the necessary permission level information.

Well, with this in mind and making use of Solr's extensive documentation for newb developers I tried to come up with a simple custom requestHandler that overrides the handleRequest function in order to inject the necessary extra parameters in the SolrQueryRequest. All is fine and dandy - except that I never see any difference at all in the QueryResponse, the server rudely ignoring my little manipulation. After a couple of days searching the web without so much of a hint weather if this the best approach, finally decided to come up and bother the fine folks here at StackOverflow.

So, in short, my questions are:

  • Is this a correct approach? Are there other alternatives? I can already grasp some of Solr's concepts, but admittedly there is much lacking and its entirely possible that am missing something.

  • If so, after modifying the query parameters is there anything I should do to force the QueryResponse to be updated? As far as I can tell these are merely encapsulating http requests, and I fail to sniff anything querying the server after the modifications are made.

Thanks in advance and so very sorry for the long post!

UPDATE

After a lot of reading APIs and specially much trial and error I've managed to get a functional solution. However I still fail to understand much of Solr's internals, therefore would still appreciate some enlightening. Feel free to bash at will, am still very aware of my rookiness.

The relevant part of the solution is this function which is called from by overriden 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);

}

Basically the search query is not modified in any way, and instead a filter is applied containing the PermissionLevel of the user. Even so, why doesn't the following alternative work? The search query works perfectly when applied in the standard requestHandler, while in this case it simply doesn't hit any document.

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);

}


回答1:


Good news: you don't need to write any code to do that, you just have to configure Solr properly. The superuser would hit the standard request handler while the regular user would hit another request handler (also a solr.StandardRequestHandler) configured with an invariant with the filter query you want to force upon them.

See also http://wiki.apache.org/solr/SolrRequestHandler




回答2:


Oh well. As previously stated, the answer that worked for me. Feel free to comment or 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);
        }



回答3:


Take a look this solr wiki page it says we should first consider using Apache Manifold Framework, and if it doesn't suite your need, then write your own requestHandler



来源:https://stackoverflow.com/questions/6182183/solr-custom-requesthandler-injecting-query-parameters

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!