如何使用searchcomponent在solr响应中添加自定义响应?

时间:2017-02-14 03:38:10

标签: solr

在solr工作中面对查询返回的结果,但我希望它在将行限制为某个值后返回的文档之上完成。例如,如果q返回1500文档而我正在服用前1000行,我想要在1000而不是1500上应用faceting。我正在编写自定义搜索组件来生成facet。以下是实施:

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.IndexableField;
import org.apache.solr.handler.component.ResponseBuilder;
import org.apache.solr.handler.component.SearchComponent;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.search.DocIterator;
import org.apache.solr.search.DocList;
import org.apache.solr.search.SolrIndexSearcher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.biginfolabs.subfacet.MapSorter;

public class SubFacetComponent extends SearchComponent {
    private static Logger logger = LoggerFactory
            .getLogger(SubFacetComponent.class);
    private SolrQueryRequest req = null;
    private long numDoc = 0;

    // private static final String field = "annotations";

    @Override
    public String getDescription() {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public void prepare(ResponseBuilder arg0) throws IOException {
        // TODO Auto-generated method stub

    }

    @Override
    public void process(ResponseBuilder rb) throws IOException {
        // TODO Auto-generated method stub
        long startTime = System.currentTimeMillis();
        req = rb.req;
        String[] fields = {"annotations"}; 
//              req.getParams().getParams("facet.field");
        logger.info("Facet component");

        if (rb.getResults() != null) {
            DocList docs = rb.getResults().docList;
            numDoc = docs.size();
            for (String field : fields) {
                DocIterator docItr = docs.iterator();
                SolrIndexSearcher searcher = req.getSearcher();
                Map<String, List<String>> map = new HashMap<String, List<String>>();
                List<String> list = new ArrayList<String>();
                while (docItr.hasNext()) {
                    int docId = docItr.nextDoc();
                    Document doc = searcher.doc(docId);
                    list.add(doc.get("id"));
                    Set<String> keySet = new HashSet<String>();
                    if (doc.get(field) != null) {
                        IndexableField[] indexableFields = doc.getFields(field);
                        for (IndexableField indexableField : indexableFields) {
                            String str = indexableField.stringValue();
                            String[] pathVariableArray = str.split("/");
                            String key = "";
                            String separator = "";
                            for (String split : pathVariableArray) {
                                key += separator + split;
                                keySet.add(key);
                                separator = "/";
                            }
                        }
                        for (String str : keySet) {
                            List<String> arrayList = new ArrayList<String>();
                            if (map.containsKey(str)) {
                                arrayList = map.get(str);
                            }
                            arrayList.add(doc.getField("_version_").toString());
                            map.put(str, arrayList);
                        }
                    }
                }
                System.out.println(list);
                Map<String, Integer> finalMap = new HashMap<String, Integer>();
                for (String key : map.keySet()) {
                    if (map.containsKey(key)) {
                        finalMap.put(key, map.get(key).size());
                        System.out.println(key + ": " + map.get(key).size());
                    }
                }
                Map<String, TreeMap<String, Integer>> facetMap = new HashMap<String, TreeMap<String, Integer>>();
                TreeMap<String, Integer> sortedMap = new TreeMap(new MapSorter(
                        finalMap));
                sortedMap.putAll(finalMap);
                rb.rsp.add("subfacet", sortedMap);
            }

        } else {
            logger.warn("You must specify 'subfacet' params in solr query !!");
        }

        long enTime = System.currentTimeMillis();
        logger.info("Time taken to generate facets for  " + numDoc
                + " documents is " + (enTime - startTime) + " ms");
    }

}

我正在尝试使用rb.rsp.add("subfacet", sortedMap);添加响应,这似乎是在rsp对象中设置子面,但是返回到solr UI的响应不包含此对象。我在这里缺少什么? 以下是我的选择请求处理程序:

<requestHandler name="/select" class="solr.SearchHandler">
    <!-- default values for query parameters can be specified, these
         will be overridden by parameters in the request
      -->
     <lst name="defaults">
       <str name="echoParams">explicit</str>
       <int name="rows">10</int>
     </lst>
      <arr name="last-components">
      <str>subfacetcomponent</str>
    </arr>

    </requestHandler>

编辑:如果solr用作单个节点和单个分片但在云模式下不可用,则它可以正常工作。

1 个答案:

答案 0 :(得分:0)

通过在public void finishStage(ResponseBuilder rb)而不是process()中覆盖和编写逻辑来修复它。