private static DrillDownQuery addDrillDowns(long timestampSec,IndexState state,Request r,Query q,Map<String,FieldDef> dynamicFields){
  DrillDownQuery ddq=new DrillDownQuery(state.facetsConfig,q);
  if (r.hasParam("drillDowns")) {
    List<Object> drillDownList=r.getList("drillDowns");
    if (!drillDownList.isEmpty()) {
      for (      Object o : drillDownList) {
        Request fr=(Request)o;
        String f=fr.getString("field");
        FieldDef fd=dynamicFields.get(f);
        if (fd == null) {
          fr.fail("field","field \"" + f + "\" was not registered and was not specified as a dynamicField");
          fd=null;
        }
        if (fr.hasParam("query")) {
          ddq.add(fd.name,parseQuery(timestampSec,null,state,r.getStruct("query"),fd.name,null,dynamicFields));
        }
 else         if (fr.hasParam("numericRange")) {
          Request rr=fr.getStruct("numericRange");
          Range range;
          if (fd.valueType == FieldDef.FieldValueType.INT || fd.valueType == FieldDef.FieldValueType.LONG) {
            range=new LongRange(rr.getString("label"),rr.getLong("min"),rr.getBoolean("minInclusive"),rr.getLong("max"),rr.getBoolean("maxInclusive"));
          }
 else           if (fd.valueType == FieldDef.FieldValueType.FLOAT || fd.valueType == FieldDef.FieldValueType.DOUBLE || fd.valueType == FieldDef.FieldValueType.VIRTUAL) {
            range=new DoubleRange(rr.getString("label"),rr.getDouble("min"),rr.getBoolean("minInclusive"),rr.getDouble("max"),rr.getBoolean("maxInclusive"));
          }
 else {
            fr.fail("numericRange","field \"" + fd.name + "\" is not numeric");
            range=null;
          }
          ValueSource valueSource;
          if (fd.valueSource == null) {
            if (fd.valueType == FieldDef.FieldValueType.INT) {
              valueSource=new IntFieldSource(fd.name);
            }
 else             if (fd.valueType == FieldDef.FieldValueType.LONG) {
              valueSource=new LongFieldSource(fd.name);
            }
 else             if (fd.valueType == FieldDef.FieldValueType.DOUBLE) {
              valueSource=new DoubleFieldSource(fd.name);
            }
 else             if (fd.valueType == FieldDef.FieldValueType.FLOAT) {
              valueSource=new FloatFieldSource(fd.name);
            }
 else {
              fr.fail("numericRange","currently only supported for virtual and numeric fields");
              valueSource=null;
            }
          }
 else {
            valueSource=fd.valueSource;
          }
          ddq.add(fd.name,range.getQuery(null,valueSource));
        }
 else {
          String[] path;
          if (fr.isString("value")) {
            path=new String[]{fr.getString("value")};
          }
 else {
            List<Object> values=fr.getList("value");
            path=new String[values.size()];
            for (int i=0; i < path.length; i++) {
              path[i]=(String)values.get(i);
            }
          }
          ddq.add(fd.name,path);
        }
      }
    }
  }
  return ddq;
}

private static DrillDownQuery addDrillDowns ( long timestampSec , IndexState state , Request r , Query q , Map < String , FieldDef > dynamicFields ) { DrillDownQuery ddq = new DrillDownQuery ( state . facetsConfig , q ) ; if ( r . hasParam ( "drillDowns" ) ) { List < Object > drillDownList = r . getList ( "drillDowns" ) ; if ( ! drillDownList . isEmpty ( ) ) { for ( Object o : drillDownList ) { Request fr = ( Request ) o ; String f = fr . getString ( "field" ) ; FieldDef fd = dynamicFields . get ( f ) ; if ( fd == null ) { fr . fail ( "field" , "field \"" + f + "\" was not registered and was not specified as a dynamicField" ) ; fd = null ; } if ( fr . hasParam ( "query" ) ) { ddq . add ( fd . name , parseQuery ( timestampSec , null , state , r . getStruct ( "query" ) , fd . name , null , dynamicFields ) ) ; } else if ( fr . hasParam ( "numericRange" ) ) { Request rr = fr . getStruct ( "numericRange" ) ; Range range ; if ( fd . valueType == FieldDef . FieldValueType . INT || fd . valueType == FieldDef . FieldValueType . LONG ) { range = new LongRange ( rr . getString ( "label" ) , rr . getLong ( "min" ) , rr . getBoolean ( "minInclusive" ) , rr . getLong ( "max" ) , rr . getBoolean ( "maxInclusive" ) ) ; } else if ( fd . valueType == FieldDef . FieldValueType . FLOAT || fd . valueType == FieldDef . FieldValueType . DOUBLE || fd . valueType == FieldDef . FieldValueType . VIRTUAL ) { range = new DoubleRange ( rr . getString ( "label" ) , rr . getDouble ( "min" ) , rr . getBoolean ( "minInclusive" ) , rr . getDouble ( "max" ) , rr . getBoolean ( "maxInclusive" ) ) ; } else { fr . fail ( "numericRange" , "field \"" + fd . name + "\" is not numeric" ) ; range = null ; } ValueSource valueSource ; if ( fd . valueSource == null ) { if ( fd . valueType == FieldDef . FieldValueType . INT ) { valueSource = new IntFieldSource ( fd . name ) ; } else if ( fd . valueType == FieldDef . FieldValueType . LONG ) { valueSource = new LongFieldSource ( fd . name ) ; } else if ( fd . valueType == FieldDef . FieldValueType . DOUBLE ) { valueSource = new DoubleFieldSource ( fd . name ) ; } else if ( fd . valueType == FieldDef . FieldValueType . FLOAT ) { valueSource = new FloatFieldSource ( fd . name ) ; } else { fr . fail ( "numericRange" , "currently only supported for virtual and numeric fields" ) ; valueSource = null ; } } else { valueSource = fd . valueSource ; } ddq . add ( fd . name , range . getQuery ( null , valueSource ) ) ; } else { String [ ] path ; if ( fr . isString ( "value" ) ) { path = new String [ ] { fr . getString ( "value" ) } ; } else { List < Object > values = fr . getList ( "value" ) ; path = new String [ values . size ( ) ] ; for ( int i = 0 ; i < path . length ; i ++ ) { path [ i ] = ( String ) values . get ( i ) ; } } ddq . add ( fd . name , path ) ; } } } } return ddq ; }
fold in any drilldowns requests into the query .
