土豆片(http://www.tudoupian.com)开发采用更加灵活的solr搜索服务器来实现分层功能。
1.QueryResponse类:
public class QueryResponse extends SolrResponseBase { // Direct pointers to known types private NamedList<Object> _header = null; private SolrDocumentList _results = null; private NamedList<ArrayList> _sortvalues = null; private NamedList<Object> _facetInfo = null; private NamedList<Object> _debugInfo = null; private NamedList<Object> _highlightingInfo = null; private NamedList<Object> _spellInfo = null; // Facet stuff private Map<String,Integer> _facetQuery = null; private List<FacetField> _facetFields = null; private List<FacetField> _limitingFacets = null; private List<FacetField> _facetDates = null; // Highlight Info private Map<String,Map<String,List<String>>> _highlighting = null; // SpellCheck Response private SpellCheckResponse _spellResponse = null; // Debug Info private Map<String,Object> _debugMap = null; private Map<String,String> _explainMap = null; // utility variable used for automatic binding -- it should not be serialized private transient final SolrServer solrServer; //..... //..... private void extractFacetInfo( NamedList<Object> info ) { // Parse the queries _facetQuery = new HashMap<String, Integer>(); NamedList<Integer> fq = (NamedList<Integer>) info.get( "facet_queries" ); for( Map.Entry<String, Integer> entry : fq ) { _facetQuery.put( entry.getKey(), entry.getValue() ); } // Parse the facet info into fields // TODO?? The list could be <int> or <long>? If always <long> then we can switch to <Long> NamedList<NamedList<Number>> ff = (NamedList<NamedList<Number>>) info.get( "facet_fields" ); if( ff != null ) { _facetFields = new ArrayList<FacetField>( ff.size() ); _limitingFacets = new ArrayList<FacetField>( ff.size() ); long minsize = _results.getNumFound(); for( Map.Entry<String,NamedList<Number>> facet : ff ) { FacetField f = new FacetField( facet.getKey() ); for( Map.Entry<String, Number> entry : facet.getValue() ) { f.add( entry.getKey(), entry.getValue().longValue() ); } _facetFields.add( f ); FacetField nl = f.getLimitingFields( minsize ); if( nl.getValueCount() > 0 ) { _limitingFacets.add( nl ); } } } //Parse date facets NamedList<NamedList<Object>> df = (NamedList<NamedList<Object>>) info.get("facet_dates"); if (df != null) { // System.out.println(df); _facetDates = new ArrayList<FacetField>( df.size() ); for (Map.Entry<String, NamedList<Object>> facet : df) { // System.out.println("Key: " + facet.getKey() + " Value: " + facet.getValue()); NamedList<Object> values = facet.getValue(); String gap = (String) values.get("gap"); Date end = (Date) values.get("end"); FacetField f = new FacetField(facet.getKey(), gap, end); for (Map.Entry<String, Object> entry : values) { try { f.add(entry.getKey(), Long.parseLong(entry.getValue().toString())); } catch (NumberFormatException e) { //Ignore for non-number responses which are already handled above } } _facetDates.add(f); } } } }
_facetFields:所有的分层结果 使用 getFacetField(String name) 获得结果
_limitingFacets:facetFields中个数大于0的分层,使用getLimitingFacets()返回所有Count个数大于0的FacetField。
_facetDates:根据日期的分层结果 getFacetDate(String name)
例外,要使用Facet功能,除了设置 Field外,还需要将facet属性设置为true,默认是false的。
params.set("facet", "true"); params.set("facet.field", "site_search"); params.set("facet.field", "kindtag_search");