【问题标题】:How to add custom response in solr response using searchcomponent?如何使用 searchcomponent 在 solr 响应中添加自定义响应?
【发布时间】:2017-02-19 04:49:50
【问题描述】:

solr 中的 Faceting 对查询返回的结果进行处理,但我希望它在将行限制为某个值后返回的文档之上完成。例如,如果 q 返回 1500 个文档,我先取 1000 个行,我希望在 1000 而不是 1500 上应用分面。我正在编写一个自定义搜索组件来生成分面。以下是实现:

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 对象中设置 subfacet,但返回到 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 用作单节点和单分片但不是在云模式下,它可以正常工作。

【问题讨论】:

    标签: solr


    【解决方案1】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-12-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-01
      相关资源
      最近更新 更多