简短问题:我正在寻找一种方法(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" />