zoukankan      html  css  js  c++  java
  • 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<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);  
          }  
        }  
      }  

    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的。

    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<Count> _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<Count> _values = null;
       private String _gap = null;
       private Date _end = null;

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

       }
     

    一个FacetField实例拥有多个Count实例。

  • 相关阅读:
    一根网线实现双机互联共享文件
    预编译指令与宏定义
    程序的编译链接过程
    windows消息机制(MFC)
    【SpringBoot】SpringBoot Servlet容器(十一)
    【SpringBoot】SpringBoot Servlet三大组件 Servlet、Filter、Listener(十)
    【SpringBoot】SpringBoot 错误处理机制(九)
    【SpringBoot】SpringBoot 国际化(七)
    【SpringBoot】SpringBoot与Thymeleaf模版(六)
    【SpringBoot】SpringBoot与SpringMVC自动配置及静态资源(五)
  • 原文地址:https://www.cnblogs.com/wycg1984/p/1575531.html
Copyright © 2011-2022 走看看