问题描述
|
简短问题:
我正在寻找一种方法(java)来拦截对Solr的查询并注入我的业务逻辑提供的一些额外的过滤参数。我应该使用什么结构?
内容:
首先,要坦白一点:我是Solr的新秀。对我而言,设置服务器,定义架构,对功能性索引管理器进行编码,然后实际上看到服务器返回正确的结果-完全符合预期! -本身已经是很大的成就。是的,我!
但是,我目前正在一个企业项目中工作,而这个项目所需要的还不止于此。粗略地说,数千个用户将通过相同的requestHandler查询solr实例,因为返回的文档会根据用户的权限级别自动进行过滤。例如,如果用户A和超级用户B都尝试了相同的搜索参数(甚至是相同的url),则用户B将获得用户A \的所有文件,然后再获取更多文件。为了做到这一点,已经用必要的权限级别信息对文档进行了索引。
好吧,考虑到这一点并利用Solr为新手开发人员提供的大量文档,我尝试提出一个简单的自定义requestHandler,该自定义请求处理程序将覆盖handleRequest函数,以便在SolrQueryRequest中注入必要的额外参数。一切都很好,很花哨-只是我从没在QueryResponse中看到任何区别,服务器无礼地忽略了我的一点操作。经过两天的搜寻,如果没有最好的办法,天气就没有那么多了,但终于决定出现,并在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>(),searcher.getReader(),true);
}
基本上,不会以任何方式修改搜索查询,而是应用包含用户的PermissionLevel的过滤器。即便如此,以下替代方法为何不起作用?当在标准requestHandler中应用搜索查询时,它可以完美地工作,但在这种情况下,它根本不会命中任何文档。
private void SearchDocumentsTypeII(SolrDocumentList results,ParseException {
String qFiltered = q + \" AND \" + \"PermissionLevel:\" + up.getPermissionLevel();
QueryParser qp = new QueryParser(qFiltered,new StandardAnalyzer());
Query query = qp.parse(qFiltered);
append (results,true);
}
解决方法
好消息:您不需要编写任何代码即可,只需正确配置Solr。超级用户将命中标准请求处理程序,而普通用户将命中另一个配置有不变量且要强加给他们的过滤器查询的请求处理程序(也是2)。
另请参见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>(),searcher.getReader(),true);
}
, 看看这个Solr Wiki页面,它说我们应该首先考虑使用Apache Manifold Framework,如果它不能满足您的需求,那么编写您自己的requestHandler