我有一个有趣的用例,我们有一个Solr实现,其中在执行查询时不应返回Solr Schema中的某些字段。理想的解决方案是更改调用程序,使其不像现在一样查询&fl=score
,只请求必要的字段,但这不会在短期内发生,所以在此期间我们必须过滤掉Solr响应中的一些字段。
我们认为对性能影响最小的方法(让我知道是否有更好的方法),是覆盖&fl=
参数,以便列出所有字段,但应该过滤的字段出。为此,我们在RequestHandler组件列表中添加了一个新的SearchComponent,用于修改&fl
参数。我们遇到的问题是,一旦我们从SolrParams
获得SolrQueryRequest
,它就无法修改(我认为这是正确的做法,因为它可能会改变另一个SearchComponent依赖于)。但是我们仍然需要找到一种方法来删除这些额外的字段。
所以,这是我们开始编写的代码:
public void prepare(ResponseBuilder rb) throws IOException {
SolrQueryRequest req = rb.req;
SolrParams params = req.getParams();
String fl = params.get("fl");
//Remove the "fl" parameter from params and replace it with a new list:
//Cannot be done"
...
遇到了无法添加到SolrParams
的问题。
作为计划B,同一个SearchComponent正在删除process()
方法中的字段,但这样做的速度较慢。代码必须通过生成的SolrDocumentList,并为每个SolrDocument调用removeFields()
,类似于:(简化代码)
public void process(ResponseBuilder rb) throws IOException {
...
SolrQueryResponse rsp = rb.rsp;
NamedList values = rsp.getValues();
SolrDocumentList docs = (SolrDocumentList) values.get("response");
Iterator<SolrDocument> docsIterator = sdoclist.iterator();
while (docsIterator.hasNext()) {
SolrDocument sd = sdocIterator.next();
sd.removeFields(field);
...
关于如何实现这一目标的任何想法?
感谢您的任何建议!
答案 0 :(得分:1)
使用您自己的SearchHandler,您可以在任何查询参数上指定不变量(无论请求总是会被修复的东西),其中包括&amp; fl。
这就是:
<requestHandler name="filtered" class="solr.StandardRequestHandler">
<lst name="invariants">
<str name="fl">score,id,something_else,etc.</bool>
</lst>
</requestHandler>
更多文档: http://wiki.apache.org/solr/SearchHandler
唯一的问题是,目前,没有负的fl参数(即返回除我告诉你的那些以外的所有字段)。 https://issues.apache.org/jira/browse/SOLR-3191
最后,要指定在查询时使用哪个SearchHandler,只需添加&amp; qt = filtered (或您使用的名称)
答案 1 :(得分:0)
尝试从ReturnFields
对象中删除不需要的字段。
例如,像这样:
@Override
public void process(ResponseBuilder rb) throws IOException {
String fl = rb.req.getParams().get(CommonParams.FL);
List<String> fields = Lists.newArrayList(fl.split(","));
List<String> newFields = Lists.newArrayList();
for (String field : fields) {
if (!field.equals("score")) {
newFields.add(field);
}
}
String newFl = Joiner.on(",").join(newFields);
ReturnFields returnFields = new ReturnFields(newFl, rb.req);
rb.rsp.setReturnFields(returnFields);
}
我在solrconfig.xml的“last-components”中设置了自定义SearchComponent
。
P.S:我在列表和Joiner中使用了番石榴库。