/** * Creates an instance of StatsValues which supports values from the specified {@link StatsField} * * @param statsField {@link StatsField} whose statistics will be created by the resulting {@link * StatsValues} * @return Instance of {@link StatsValues} that will create statistics from values from the * specified {@link StatsField} */ public static StatsValues createStatsValues(StatsField statsField) { final SchemaField sf = statsField.getSchemaField(); if (null == sf) { // function stats return new NumericStatsValues(statsField); } final FieldType fieldType = sf.getType(); // TODO: allow FieldType to provide impl. if (TrieDateField.class.isInstance(fieldType)) { return new DateStatsValues(statsField); } else if (TrieField.class.isInstance(fieldType)) { return new NumericStatsValues(statsField); } else if (StrField.class.isInstance(fieldType)) { return new StringStatsValues(statsField); } else if (sf.getType().getClass().equals(EnumField.class)) { return new EnumStatsValues(statsField); } else { throw new SolrException( SolrException.ErrorCode.BAD_REQUEST, "Field type " + fieldType + " is not currently supported"); } }
protected AbstractStatsValues(StatsField statsField) { this.statsField = statsField; this.computeCount = statsField.calculateStats(Stat.count); this.computeMissing = statsField.calculateStats(Stat.missing); this.computeCalcDistinct = statsField.calculateStats(Stat.countDistinct) || statsField.calculateStats(Stat.distinctValues); this.computeMin = statsField.calculateStats(Stat.min); this.computeMax = statsField.calculateStats(Stat.max); this.computeMinOrMax = computeMin || computeMax; this.distinctValues = computeCalcDistinct ? new TreeSet<T>() : null; this.computeCardinality = statsField.calculateStats(Stat.cardinality); if (computeCardinality) { hasher = statsField.getHllOptions().getHasher(); hll = statsField.getHllOptions().newHLL(); assert null != hll : "Cardinality requires an HLL"; } else { hll = null; hasher = null; } // alternatively, we could refactor a common base class that doesn't know/care // about either SchemaField or ValueSource - but then there would be a lot of // duplicate code between "NumericSchemaFieldStatsValues" and // "NumericValueSourceStatsValues" which would have diff parent classes // // part of the complexity here being that the StatsValues API serves two // masters: collecting concrete Values from things like DocValuesStats and // the distributed aggregation logic, but also collecting docIds which it // then // uses to go out and pull concreate values from the ValueSource // (from a func, or single valued field) if (null != statsField.getSchemaField()) { assert null == statsField.getValueSource(); this.sf = statsField.getSchemaField(); this.ft = sf.getType(); } else { assert null != statsField.getValueSource(); assert null == statsField.getSchemaField(); this.sf = null; this.ft = null; } }