Solr自定义RequestHandler-注入查询参数



简短问题:我正在寻找一种方法(java)来拦截对Solr的查询,并注入一些由我的业务逻辑提供的额外过滤参数。我应该使用什么结构?

上下文:首先,我有一点坦白:我对索尔是个新手。对我来说,设置一个服务器,定义一个模式,编码一个函数索引管理器,然后实际看到服务器返回正确的结果-完全符合预期!-这本身就已经是一项成就。是我!

然而,我目前正在一个需要更多的企业项目中工作。粗略地说,solr实例将由成千上万的用户通过同一个requestHandler进行查询,因为返回的文档将根据用户的权限级别自动过滤。例如,如果用户A和超级用户B都尝试了非常相同的搜索参数(甚至是非常相同的url),则用户B将获得用户A的所有文件,然后再获得更多文件。为了实现这一点,文档已经使用必要的权限级别信息进行了索引。

考虑到这一点,并利用Solr为新手开发人员提供的大量文档,我尝试提出一个简单的自定义requestHandler,它覆盖handleRequest函数,以便在SolrQueryRequest中注入必要的额外参数。一切都很好,只是我从未在QueryResponse中看到任何区别,服务器粗暴地忽略了我的小操作。经过几天的网络搜索,没有太多关于天气的提示,如果这是最好的方法,最终决定来打扰StackOverflow的好心人。

简而言之,我的问题是:

  • 这是一个正确的方法吗?还有其他选择吗?我已经掌握了Solr的一些概念,但无可否认,其中有很多不足,完全有可能是缺少了一些东西。

  • 如果是的话,在修改查询参数之后,我应该做些什么来强制更新QueryResponse吗?据我所知,这些只是封装http请求,在进行修改后,我无法嗅到任何查询服务器的信息。

提前感谢,非常抱歉发了这么长的帖子!

更新

经过大量的API阅读,特别是大量的试错,我终于找到了一个功能性的解决方案。然而,我仍然不了解Solr的很多内部内容,因此我仍然会欣赏一些启发性的东西。随意抨击,我还是很清楚我的菜鸟。

解决方案的相关部分是这个函数,它由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);

}

基本上,搜索查询不会以任何方式进行修改,而是应用一个包含用户的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);

}

好消息:您不需要编写任何代码,只需要正确配置Solr即可。超级用户将命中标准请求处理程序,而普通用户将命中另一个请求处理程序(也是solr.StandardRequestHandler),该请求处理程序配置有您想要强制执行的过滤器查询的不变量。

另请参阅http://wiki.apache.org/solr/SolrRequestHandler

哦,好吧。如前所述,答案对我有效。欢迎评论或抨击!

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

看看这个solr wiki页面,它说我们应该首先考虑使用Apache Manifold Framework,如果它不能满足您的需求,那么编写您自己的requestHandler

我有完全相同的要求。如果有人看到这一点,这里是我的解决方案。

请求处理程序

public class SearchRequestHanlder extends SearchHandler {
  @Override
  public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp) throws Exception {
    var map = req.getParams();
    if (map instanceof MultiMapSolrParams) {
      MultiMapSolrParams m = (MultiMapSolrParams) map;
      MultiMapSolrParams.addParam("bq", "category:film^220", m.getMap());
    }
    super.handleRequestBody(req, rsp);
  }
  @Override
  public String getDescription() {
    return "Custom SearchRequestHanlder";
  }
}

solrconf.xml

<lib dir="/opt/solr/data/cores/movies/lib" regex=".*.jar" />
<!-- Make sure following line is after existing default <requestHandler name="/select" -->
<requestHandler name="/select" class="com.solrplugin.SearchRequestHanlder" />

相关内容

  • 没有找到相关文章

最新更新