saundy 发表于 2015-7-16 13:51:32

solr的facet解读

  开发采用更加灵活的solr搜索服务器来实现分层功能。
  1.QueryResponse类:
  view plaincopy to clipboardprint?
·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
public class QueryResponse extends SolrResponseBase   
{   
// Direct pointers to known types   
private NamedList _header = null;   
private SolrDocumentList _results = null;   
private NamedList _sortvalues = null;   
private NamedList _facetInfo = null;   
private NamedList _debugInfo = null;   
private NamedList _highlightingInfo = null;   
private NamedList _spellInfo = null;   

// Facet stuff   
private Map _facetQuery = null;   
private List _facetFields = null;   
private List _limitingFacets = null;   
private List _facetDates = null;   

// Highlight Info   
private Map _highlighting = null;   

// SpellCheck Response   
private SpellCheckResponse _spellResponse = null;   
   
// Debug Info   
private Map _debugMap = null;   
private Map _explainMap = null;   

// utility variable used for automatic binding -- it should not be serialized   
private transient final SolrServer solrServer;   
//.....   
//.....   
private void extractFacetInfo( NamedList info )   
{   
    // Parse the queries   
    _facetQuery = new HashMap();   
    NamedList fq = (NamedList) info.get( "facet_queries" );   
    for( Map.Entry entry : fq ) {   
      _facetQuery.put( entry.getKey(), entry.getValue() );   
    }   
      
    // Parse the facet info into fields   
    // TODO?? The list could beor ?If alwaysthen we can switch to   
    NamedList ff = (NamedList) info.get( "facet_fields" );   
    if( ff != null ) {   
      _facetFields = new ArrayList( ff.size() );   
      _limitingFacets = new ArrayList( ff.size() );   
         
      long minsize = _results.getNumFound();   
      for( Map.Entry facet : ff ) {   
      FacetField f = new FacetField( facet.getKey() );   
      for( Map.Entry 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 df = (NamedList) info.get("facet_dates");   
    if (df != null) {   
      // System.out.println(df);   
      _facetDates = new ArrayList( df.size() );   
      for (Map.Entry facet : df) {   
      // System.out.println("Key: " + facet.getKey() + " Value: " + facet.getValue());   
      NamedList 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 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);   
      }   
    }   
}   
}
public class QueryResponse extends SolrResponseBase
{
// Direct pointers to known types
private NamedList _header = null;
private SolrDocumentList _results = null;
private NamedList _sortvalues = null;
private NamedList _facetInfo = null;
private NamedList _debugInfo = null;
private NamedList _highlightingInfo = null;
private NamedList _spellInfo = null;
  // Facet stuff
private Map _facetQuery = null;
private List _facetFields = null;
private List _limitingFacets = null;
private List _facetDates = null;
  // Highlight Info
private Map _highlighting = null;
  // SpellCheck Response
private SpellCheckResponse _spellResponse = null;

// Debug Info
private Map _debugMap = null;
private Map _explainMap = null;
  // utility variable used for automatic binding -- it should not be serialized
private transient final SolrServer solrServer;
//.....
//.....
private void extractFacetInfo( NamedList info )
{
    // Parse the queries
    _facetQuery = new HashMap();
    NamedList fq = (NamedList) info.get( "facet_queries" );
    for( Map.Entry entry : fq ) {
      _facetQuery.put( entry.getKey(), entry.getValue() );
    }
   
    // Parse the facet info into fields
    // TODO?? The list could beor ?If alwaysthen we can switch to
    NamedList ff = (NamedList) info.get( "facet_fields" );
    if( ff != null ) {
      _facetFields = new ArrayList( ff.size() );
      _limitingFacets = new ArrayList( ff.size() );
      
      long minsize = _results.getNumFound();
      for( Map.Entry facet : ff ) {
      FacetField f = new FacetField( facet.getKey() );
      for( Map.Entry 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 df = (NamedList) info.get("facet_dates");
    if (df != null) {
      // System.out.println(df);
      _facetDates = new ArrayList( df.size() );
      for (Map.Entry facet : df) {
      // System.out.println("Key: " + facet.getKey() + " Value: " + facet.getValue());
      NamedList 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 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的。
  view plaincopy to clipboardprint?
params.set("facet", "true");   
params.set("facet.field", "site_search");   
params.set("facet.field", "kindtag_search");
  

  1. FacetField 内嵌了 Count类,Count类保存了被分层出来的的 词 以及该词在搜有搜索出来的文档中出现的次数。
  
view plaincopy to clipboardprint?
package org.apache.solr.client.solrj.response;   

import java.io.Serializable;   
import java.util.ArrayList;   
import java.util.Date;   
import java.util.List;   

import org.apache.solr.client.solrj.util.ClientUtils;   
   
/**
* A utility class to hold the facet response.It could use the NamedList container,
* but for JSTL, it is nice to have something that implements List so it can be iterated
*   
* @version $Id: FacetField.java 638357 2008-03-18 13:12:27Z gsingers $
* @since solr 1.3
*/
public class FacetField implements Serializable   
{   
   public static class Count implements Serializable   
   {   
   private String _name = null;   
   private long _count = 0;   
   // hang onto the FacetField for breadcrumb creation convenience   
   private FacetField _ff = null;   
      
   public Count( FacetField ff, String n, long c )   
   {   
       _name = n;   
       _count = c;   
       _ff = ff;   
   }   
      
   public String getName() {   
       return _name;   
   }   
      
   public void setName( String n )   
   {   
       _name = n;   
   }   

   public long getCount() {   
       return _count;   
   }   
      
   public void setCount( long c )   
   {   
       _count = c;   
   }   
      
   public FacetField getFacetField() {   
       return _ff;   
   }   
      
   @Override
   public String toString()   
   {   
       return _name+" ("+_count+")";   
   }   
      
   public String getAsFilterQuery() {   
       if (_ff.getName().equals("facet_queries")) {   
         return _name;   
       }   
       return   
          ClientUtils.escapeQueryChars( _ff._name ) + ":" +   
          ClientUtils.escapeQueryChars( _name );   
   }   
   }   
      
   private String      _name   = null;   
   private List _values = null;   
   private String _gap = null;   
   private Date _end = null;   

//.........   
//.........方法   

   }
package org.apache.solr.client.solrj.response;
  import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
  import org.apache.solr.client.solrj.util.ClientUtils;

/**
* A utility class to hold the facet response.It could use the NamedList container,
* but for JSTL, it is nice to have something that implements List so it can be iterated
*
* @version $Id: FacetField.java 638357 2008-03-18 13:12:27Z gsingers $
* @since solr 1.3
*/
public class FacetField implements Serializable
{
   public static class Count implements Serializable
   {
   private String _name = null;
   private long _count = 0;
   // hang onto the FacetField for breadcrumb creation convenience
   private FacetField _ff = null;
   
   public Count( FacetField ff, String n, long c )
   {
       _name = n;
       _count = c;
       _ff = ff;
   }
   
   public String getName() {
       return _name;
   }
   
   public void setName( String n )
   {
       _name = n;
   }
  public long getCount() {
       return _count;
   }
   
   public void setCount( long c )
   {
       _count = c;
   }
   
   public FacetField getFacetField() {
       return _ff;
   }
   
   @Override
   public String toString()
   {
       return _name+" ("+_count+")";
   }
   
   public String getAsFilterQuery() {
       if (_ff.getName().equals("facet_queries")) {
         return _name;
       }
       return
          ClientUtils.escapeQueryChars( _ff._name ) + ":" +
          ClientUtils.escapeQueryChars( _name );
   }
   }
   
   private String      _name   = null;
   private List _values = null;
   private String _gap = null;
   private Date _end = null;
  //.........
//.........方法
  }

  一个FacetField实例拥有多个Count实例。
  
  
页: [1]
查看完整版本: solr的facet解读