Package org.apache.solr.client.solrj.response

Source Code of org.apache.solr.client.solrj.response.QueryResponse

/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License.  You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.solr.client.solrj.response;

import org.apache.solr.client.solrj.SolrServer;
import org.apache.solr.client.solrj.beans.DocumentObjectBinder;
import org.apache.solr.common.SolrDocumentList;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.common.util.SimpleOrderedMap;

import java.util.*;

/**
*
* @version $Id: QueryResponse.java 1180378 2011-10-08 14:14:08Z mvg $
* @since solr 1.3
*/
@SuppressWarnings("unchecked")
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 Object _mdrillData = null;
  public Object get_mdrillData() {
  return _mdrillData;
}


private NamedList<Object> _debugInfo = null;
  private NamedList<Object> _highlightingInfo = null;
  private NamedList<Object> _spellInfo = null;
  private NamedList<Object> _statsInfo = null;
  private NamedList<Object> _termsInfo = null;

  // Grouping response
  private NamedList<Object> _groupedInfo = null;
  private GroupResponse _groupResponse = null;

  // Facet stuff
  private Map<String,Integer> _facetQuery = null;
  private List<FacetField> _facetFields = null;
  private List<FacetField> _limitingFacets = null;
  private List<FacetField> _facetDates = null;
  private List<RangeFacet> _facetRanges = null;

  // Highlight Info
  private Map<String,Map<String,List<String>>> _highlighting = null;

  // SpellCheck Response
  private SpellCheckResponse _spellResponse = null;

  // Terms Response
  private TermsResponse _termsResponse = null;
 
  // Field stats Response
  private Map<String,FieldStatsInfo> _fieldStatsInfo = 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;
 
  public QueryResponse(){
    solrServer = null;
  }
 
  /**
   * Utility constructor to set the solrServer and namedList
   */
  public QueryResponse( NamedList<Object> res , SolrServer solrServer){
    this.setResponse( res );
    this.solrServer = solrServer;
  }

 
  Map<String,String> timetaken=new LinkedHashMap<String,String>();
  public ArrayList<String> getTimetaken(int n) {
    Map<String,ArrayList<String>> rtn=new HashMap<String,ArrayList<String>>();
    for(Map.Entry<String,String> e:timetaken.entrySet())
    {
      String key=e.getKey();
      String val=e.getValue();
      String[] arr=key.split("@");
     
      ArrayList<String> list=rtn.get(arr[0]);
      if(list==null)
      {
        list=new ArrayList<String>();
        rtn.put(arr[0], list);
      }
     
      list.add(key+"@"+val);
     
    }
   
    ArrayList<String> rtntop=new ArrayList<String>();
    for(Map.Entry<String,ArrayList<String>> e:rtn.entrySet())
    {
      ArrayList<String> list=new ArrayList<String>(e.getValue());
      Collections.sort(list,new Comparator<String>() {
        @Override
        public int compare(String o1, String o2) {
          String[] arr1=o1.split("@");
          String[] arr2=o2.split("@");
          int cmp1=0;
          if(arr1.length>3&&arr2.length>3)
          {
            cmp1=arr2[3].compareTo(arr1[3]);
          }
          if(cmp1==0)
          {
            cmp1=o2.compareTo(o1);
          }
          return cmp1;
        }
      });
     
      rtntop.addAll(list.subList(0, Math.min(list.size(), n)));
    
     
    }
   
  return rtntop;
}

@Override
  public void setResponse( NamedList<Object> res )
  {
    super.setResponse( res );
   
    // Look for known things
    for( int i=0; i<res.size(); i++ ) {
      String n = res.getName( i );
      if( "responseHeader".equals( n ) ) {
        _header = (NamedList<Object>) res.getVal( i );
      }
      else if( "response".equals( n ) ) {
        _results = (SolrDocumentList) res.getVal( i );
      }
      else if( "sort_values".equals( n ) ) {
        _sortvalues = (NamedList<ArrayList>) res.getVal( i );
      }
      else if( "facet_counts".equals( n ) ) {
        _facetInfo = (NamedList<Object>) res.getVal( i );
        // extractFacetInfo inspects _results, so defer calling it
        // in case it hasn't been populated yet.
      }
      else if( "mdrill_data".equals( n ) ) {
        _mdrillData =  res.getVal( i );
       }
     
     
      else if( "mdrill_shard_time".equals( n ) ) {
        timetaken = (Map<String,String>) res.getVal( i );
        }
     
      else if( "debug".equals( n ) ) {
        _debugInfo = (NamedList<Object>) res.getVal( i );
        extractDebugInfo( _debugInfo );
      }
      else if( "grouped".equals( n ) ) {
        _groupedInfo = (NamedList<Object>) res.getVal( i );
        extractGroupedInfo(_groupedInfo);
      }
      else if( "highlighting".equals( n ) ) {
        _highlightingInfo = (NamedList<Object>) res.getVal( i );
        extractHighlightingInfo(_highlightingInfo);
      }
      else if ( "spellcheck".equals( n ) )  {
        _spellInfo = (NamedList<Object>) res.getVal( i );
        extractSpellCheckInfo(_spellInfo);
      }
      else if ( "stats".equals( n ) )  {
        _statsInfo = (NamedList<Object>) res.getVal( i );
        extractStatsInfo(_statsInfo);
      }
      else if ( "terms".equals( n ) ) {
        _termsInfo = (NamedList<Object>) res.getVal( i );
        extractTermsInfo( _termsInfo );
      }
    }
    if(_facetInfo != null) extractFacetInfo( _facetInfo );
  }

  private void extractSpellCheckInfo(NamedList<Object> spellInfo) {
    _spellResponse = new SpellCheckResponse(spellInfo);
  }

  private void extractTermsInfo(NamedList<Object> termsInfo) {
    _termsResponse = new TermsResponse(termsInfo);
  }
 
  private void extractStatsInfo(NamedList<Object> info) {
    if( info != null ) {
      _fieldStatsInfo = new HashMap<String, FieldStatsInfo>();
      NamedList<NamedList<Object>> ff = (NamedList<NamedList<Object>>) info.get( "stats_fields" );
      if( ff != null ) {
        for( Map.Entry<String,NamedList<Object>> entry : ff ) {
          NamedList<Object> v = entry.getValue();
          if( v != null ) {
            _fieldStatsInfo.put( entry.getKey(),
                new FieldStatsInfo( v, entry.getKey() ) );
          }
        }
      }
    }
  }

  private void extractDebugInfo( NamedList<Object> debug )
  {
    _debugMap = new LinkedHashMap<String, Object>(); // keep the order
    for( Map.Entry<String, Object> info : debug ) {
      _debugMap.put( info.getKey(), info.getValue() );
    }

    // Parse out interesting bits from the debug info
    _explainMap = new HashMap<String, String>();
    NamedList<String> explain = (NamedList<String>)_debugMap.get( "explain" );
    if( explain != null ) {
      for( Map.Entry<String, String> info : explain ) {
        String key = info.getKey();
        _explainMap.put( key, info.getValue() );
      }
    }
  }

  private void extractGroupedInfo( NamedList<Object> info ) {
    if ( info != null ) {
      _groupResponse = new GroupResponse();
      int size = info.size();
      for (int i=0; i < size; i++) {
        String fieldName = info.getName(i);
        Object fieldGroups =  info.getVal(i);
        SimpleOrderedMap<Object> simpleOrderedMap = (SimpleOrderedMap<Object>) fieldGroups;

        Object oMatches = simpleOrderedMap.get("matches");
        Object oNGroups = simpleOrderedMap.get("ngroups");
        Object oGroups = simpleOrderedMap.get("groups");
        Object queryCommand = simpleOrderedMap.get("doclist");
        if (oMatches == null) {
          continue;
        }

        if (oGroups != null) {
          Integer iMatches = (Integer) oMatches;
          ArrayList<Object> groupsArr = (ArrayList<Object>) oGroups;
          GroupCommand groupedCommand;
          if (oNGroups != null) {
            Integer iNGroups = (Integer) oNGroups;
            groupedCommand = new GroupCommand(fieldName, iMatches, iNGroups);
          } else {
            groupedCommand = new GroupCommand(fieldName, iMatches);
          }

          for (Object oGrp : groupsArr) {
            SimpleOrderedMap grpMap = (SimpleOrderedMap) oGrp;
            Object sGroupValue = grpMap.get( "groupValue");
            SolrDocumentList doclist = (SolrDocumentList) grpMap.get( "doclist");
            Group group = new Group(sGroupValue != null ? sGroupValue.toString() : null, doclist) ;
            groupedCommand.add(group);
          }

          _groupResponse.add(groupedCommand);
        } else if (queryCommand != null) {
          Integer iMatches = (Integer) oMatches;
          GroupCommand groupCommand = new GroupCommand(fieldName, iMatches);
          SolrDocumentList docList = (SolrDocumentList) queryCommand;
          groupCommand.add(new Group(fieldName, docList));
          _groupResponse.add(groupCommand);
        }
      }
    }
  }

  private void extractHighlightingInfo( NamedList<Object> info )
  {
    _highlighting = new HashMap<String,Map<String,List<String>>>();
    for( Map.Entry<String, Object> doc : info ) {
      Map<String,List<String>> fieldMap = new HashMap<String, List<String>>();
      _highlighting.put( doc.getKey(), fieldMap );
     
      NamedList<List<String>> fnl = (NamedList<List<String>>)doc.getValue();
      for( Map.Entry<String, List<String>> field : fnl ) {
        fieldMap.put( field.getKey(), field.getValue() );
      }
    }
  }

  private void extractFacetInfo( NamedList<Object> info )
  {
    // Parse the queries
    _facetQuery = new LinkedHashMap<String, Integer>();
    NamedList<Integer> fq = (NamedList<Integer>) info.get( "facet_queries" );
    if (fq != null) {
      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<Object>> ff = (NamedList<NamedList<Object>>) info.get( "facet_fields" );
    if( ff != null ) {
      _facetFields = new ArrayList<FacetField>( ff.size() );
      _limitingFacets = new ArrayList<FacetField>( ff.size() );
     
      long minsize = _results == null ? Long.MAX_VALUE :_results.getNumFound();
      for( Map.Entry<String,NamedList<Object>> facet : ff ) {//遍历“facet_fields”,如果用了cross这里面只有一个值就是solrCorssFields_s。如果没用cross,就是普通情况
     
      FacetField f = new FacetField( facet.getKey() );//写"solrCorssFields_s"或者普通的facet field name到FacetField
      if(facet.getKey().equals("solrCorssFields_s")){
        //cross也有两种情况,一种是计算fl的sum,max,min。另一种是计算fl的进一步分组的组数(distinct count)
        int count1=0;
        for( Map.Entry<String, Object> entry : facet.getValue() ) {//遍历"solrCorssFields_s"
            NamedList<Object> nl = (NamedList<Object>)entry.getValue();//key是每个具体的cross串,value是具体信息的list
           
            if(count1==0){//entry.getKey().equals("recordcount")){//第一行的名字是recordcount,那么这一行就是分组的组数。
              if(nl.get("recordcount") != null){//第一行下面有count(很大的数)和recordcount(真实值)两部分
                long c = ((Number)nl.get("recordcount")).longValue();
                f.setTotal(c);
              }
            }else{
              int count2=0;
              long count=0;
              ArrayList<String> ext = new ArrayList<String>();
              for( Map.Entry<String, Object> entry2 : nl) {//遍历每个"交叉分组串"的list单元,提取count,以及fl,dist等信息
                if(count2==0){//每个组的第一行总是count
                  count = ((Number)(nl.get("count"))).longValue();//得到count
                }else{
                  //在其他行得到信息
                  if(entry2.getValue() instanceof Number){//计算distinct的情况
                    ext.add(entry2.getKey()+","+((Number)(entry2.getValue())).intValue());
                  }else if(entry2.getValue() instanceof NamedList){//计算fl的情况(sum等)
                    String name = entry2.getKey();
                    NamedList<Number> nl3 = (NamedList<Number>)entry2.getValue();
                    double sum = ((Number)(nl3.get("sum",0d))).doubleValue();
                    double max = ((Number)(nl3.get("max",0d))).doubleValue();
                    double min = ((Number)(nl3.get("min",0d))).doubleValue();
                    double dist = ((Number)(nl3.get("dist",0d))).doubleValue();
                    double cnt = ((Number)(nl3.get("cnt",0d))).doubleValue();
                    ext.add(name+","+sum+","+max+","+min+","+dist+","+cnt);
                  }
                }
                count2++;
              }
                f.add( entry.getKey(), count, ext);//写入key(cross串)和value
            }
            count1++;
          }
      }else{//不用cross,普通情况
       
        for( Map.Entry<String, Object> entry : facet.getValue() ) {
               Number value2 = (Number)entry.getValue();
               f.add( entry.getKey(), value2.longValue() , null);
          }
      }
      _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()), null);
          } catch (NumberFormatException e) {
            //Ignore for non-number responses which are already handled above
          }
        }
       
        _facetDates.add(f);
      }
    }

    //Parse range facets
    NamedList<NamedList<Object>> rf = (NamedList<NamedList<Object>>) info.get("facet_ranges");
    if (rf != null) {
      _facetRanges = new ArrayList<RangeFacet>( rf.size() );
      for (Map.Entry<String, NamedList<Object>> facet : rf) {
        NamedList<Object> values = facet.getValue();
        Object rawGap = values.get("gap");

        RangeFacet rangeFacet;
        if (rawGap instanceof Number) {
          Number gap = (Number) rawGap;
          Number start = (Number) values.get("start");
          Number end = (Number) values.get("end");

          Number before = (Number) values.get("before");
          Number after = (Number) values.get("after");

          rangeFacet = new RangeFacet.Numeric(facet.getKey(), start, end, gap, before, after);
        } else {
          String gap = (String) rawGap;
          Date start = (Date) values.get("start");
          Date end = (Date) values.get("end");

          Number before = (Number) values.get("before");
          Number after = (Number) values.get("after");

          rangeFacet = new RangeFacet.Date(facet.getKey(), start, end, gap, before, after);
        }

        NamedList<Integer> counts = (NamedList<Integer>) values.get("counts");
        for (Map.Entry<String, Integer> entry : counts)   {
          rangeFacet.addCount(entry.getKey(), entry.getValue());
        }

        _facetRanges.add(rangeFacet);
      }
    }
  }

  //------------------------------------------------------
  //------------------------------------------------------

  /**
   * Remove the field facet info
   */
  public void removeFacets() {
    _facetFields = new ArrayList<FacetField>();
  }
 
  //------------------------------------------------------
  //------------------------------------------------------

  public NamedList<Object> getHeader() {
    return _header;
  }

  public SolrDocumentList getResults() {
    return _results;
  }
  public NamedList<ArrayList> getSortValues(){
    return _sortvalues;
  }

  public Map<String, Object> getDebugMap() {
    return _debugMap;
  }

  public Map<String, String> getExplainMap() {
    return _explainMap;
  }

  public Map<String,Integer> getFacetQuery() {
    return _facetQuery;
  }

  /**
   * Returns the {@link GroupResponse} containing the group commands.
   * A group command can be the result of one of the following parameters:
   * <ul>
   *   <li>group.field
   *   <li>group.func
   *   <li>group.query
   * </ul>
   *
   * @return the {@link GroupResponse} containing the group commands
   */
  public GroupResponse getGroupResponse() {
    return _groupResponse;
  }

  public Map<String, Map<String, List<String>>> getHighlighting() {
    return _highlighting;
  }

  public SpellCheckResponse getSpellCheckResponse() {
    return _spellResponse;
  }

  public TermsResponse getTermsResponse() {
    return _termsResponse;
  }
 
  /**
   * See also: {@link #getLimitingFacets()}
   */
  public List<FacetField> getFacetFields() {
    return _facetFields;
  }
 
  public List<FacetField> getFacetDates()   {
    return _facetDates;
  }

  public List<RangeFacet> getFacetRanges() {
    return _facetRanges;
  }

  /** get
   *
   * @param name the name of the
   * @return the FacetField by name or null if it does not exist
   */
  public FacetField getFacetField(String name) {
    if (_facetFields==null) return null;
    for (FacetField f : _facetFields) {
      if (f.getName().equals(name)) return f;
    }
    return null;
  }
 
  public FacetField getFacetDate(String name)   {
    if (_facetDates == null)
      return null;
    for (FacetField f : _facetDates)
      if (f.getName().equals(name))
        return f;
    return null;
  }
 
  /**
   * @return a list of FacetFields where the count is less then
   * then #getResults() {@link SolrDocumentList#getNumFound()}
   *
   * If you want all results exactly as returned by solr, use:
   * {@link #getFacetFields()}
   */
  public List<FacetField> getLimitingFacets() {
    return _limitingFacets;
  }
 
  public <T> List<T> getBeans(Class<T> type){
    return solrServer == null ?
      new DocumentObjectBinder().getBeans(type,_results):
      solrServer.getBinder().getBeans(type, _results);
  }

  public Map<String, FieldStatsInfo> getFieldStatsInfo() {
    return _fieldStatsInfo;
  }
}


TOP

Related Classes of org.apache.solr.client.solrj.response.QueryResponse

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.