在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用作单个节点和单个分片但在云模式下不可用,则它可以正常工作。
答案 0 :(得分:0)
通过在public void finishStage(ResponseBuilder rb)
而不是process()中覆盖和编写逻辑来修复它。