/** * A recursive method for generating a NamedList from this value suitable for including in a pivot * facet response to the original distributed request. * * @see PivotFacetField#convertToListOfNamedLists */ public NamedList<Object> convertToNamedList() { NamedList<Object> newList = new SimpleOrderedMap<>(); newList.add(PivotListEntry.FIELD.getName(), parentPivot.field); newList.add(PivotListEntry.VALUE.getName(), value); newList.add(PivotListEntry.COUNT.getName(), count); if (queryCounts != null) { newList.add(PivotListEntry.QUERIES.getName(), queryCounts); } if (rangeCounts != null) { SimpleOrderedMap<SimpleOrderedMap<Object>> rangeFacetOutput = new SimpleOrderedMap<>(); for (Map.Entry<String, RangeFacetRequest.DistribRangeFacet> entry : rangeCounts.entrySet()) { String key = entry.getKey(); RangeFacetRequest.DistribRangeFacet value = entry.getValue(); rangeFacetOutput.add(key, value.rangeFacet); } newList.add(PivotListEntry.RANGES.getName(), rangeFacetOutput); } if (childPivot != null && childPivot.convertToListOfNamedLists() != null) { newList.add(PivotListEntry.PIVOT.getName(), childPivot.convertToListOfNamedLists()); } if (null != statsValues) { newList.add(PivotListEntry.STATS.getName(), StatsComponent.convertToResponse(statsValues)); } return newList; }
/** * Merges in the count contributions from the specified shard for each. This method is recursive * if the shard data includes sub-pivots * * @see PivotFacetField#contributeFromShard * @see PivotFacetField#createFromListOfNamedLists */ public void mergeContributionFromShard( int shardNumber, ResponseBuilder rb, NamedList<Object> value) { assert null != value : "can't merge in null data"; if (!shardHasContributed(shardNumber)) { sourceShards.set(shardNumber); count += PivotFacetHelper.getCount(value); NamedList<NamedList<NamedList<?>>> stats = PivotFacetHelper.getStats(value); if (stats != null) { statsValues = PivotFacetHelper.mergeStats(statsValues, stats, rb._statsInfo); } NamedList<Number> shardQueryCounts = PivotFacetHelper.getQueryCounts(value); if (shardQueryCounts != null) { queryCounts = PivotFacetHelper.mergeQueryCounts(queryCounts, shardQueryCounts); } SimpleOrderedMap<SimpleOrderedMap<Object>> shardRanges = PivotFacetHelper.getRanges(value); if (shardRanges != null) { if (rangeCounts == null) { rangeCounts = new LinkedHashMap<>(shardRanges.size() / 2); } RangeFacetRequest.DistribRangeFacet.mergeFacetRangesFromShardResponse( rangeCounts, shardRanges); } } List<NamedList<Object>> shardChildPivots = PivotFacetHelper.getPivots(value); // sub pivot -- we may not have seen this yet depending on refinement if (null == childPivot) { childPivot = PivotFacetField.createFromListOfNamedLists(shardNumber, rb, this, shardChildPivots); } else { childPivot.contributeFromShard(shardNumber, rb, shardChildPivots); } }
/** * A recursive method that walks up the tree of pivot fields/values to build a list of the String * representations of the values that lead down to this PivotFacetValue. * * @return a mutable List of the pivot value Strings leading down to and including this pivot * value, will never be null but may contain nulls * @see PivotFacetField#getValuePath */ public List<String> getValuePath() { List<String> out = parentPivot.getValuePath(); // Note: this code doesn't play nice with custom FieldTypes -- see SOLR-6330 if (null == value) { out.add(null); } else if (value instanceof Date) { out.add(DateFormatUtil.formatExternal((Date) value)); } else { out.add(value.toString()); } return out; }
/** * A recursive method to construct a new <code>PivotFacetValue</code> object from the contents of * the {@link NamedList} provided by the specified shard, relative to the specified field. * * <p>If the <code>NamedList</code> contains data for a child {@link PivotFacetField} that will be * recursively built as well. * * @see PivotFacetField#createFromListOfNamedLists * @param shardNumber the id of the shard that provided this data * @param rb The response builder of the current request * @param parentField the parent field in the current pivot associated with this value * @param pivotData the data from the specified shard for this pivot value */ @SuppressWarnings("unchecked") public static PivotFacetValue createFromNamedList( int shardNumber, ResponseBuilder rb, PivotFacetField parentField, NamedList<Object> pivotData) { Comparable pivotVal = null; int pivotCount = 0; List<NamedList<Object>> childPivotData = null; NamedList<NamedList<NamedList<?>>> statsValues = null; NamedList<Number> queryCounts = null; SimpleOrderedMap<SimpleOrderedMap<Object>> ranges = null; for (int i = 0; i < pivotData.size(); i++) { String key = pivotData.getName(i); Object value = pivotData.getVal(i); PivotListEntry entry = PivotListEntry.get(key); switch (entry) { case VALUE: pivotVal = (Comparable) value; break; case FIELD: assert parentField.field.equals(value) : "Parent Field mismatch: " + parentField.field + "!=" + value; break; case COUNT: pivotCount = (Integer) value; break; case PIVOT: childPivotData = (List<NamedList<Object>>) value; break; case STATS: statsValues = (NamedList<NamedList<NamedList<?>>>) value; break; case QUERIES: queryCounts = (NamedList<Number>) value; break; case RANGES: ranges = (SimpleOrderedMap<SimpleOrderedMap<Object>>) value; break; default: throw new RuntimeException("PivotListEntry contains unaccounted for item: " + entry); } } PivotFacetValue newPivotFacet = new PivotFacetValue(parentField, pivotVal); newPivotFacet.count = pivotCount; newPivotFacet.sourceShards.set(shardNumber); if (statsValues != null) { newPivotFacet.statsValues = PivotFacetHelper.mergeStats(null, statsValues, rb._statsInfo); } if (queryCounts != null) { newPivotFacet.queryCounts = PivotFacetHelper.mergeQueryCounts(null, queryCounts); } if (ranges != null) { newPivotFacet.rangeCounts = new LinkedHashMap<>(); RangeFacetRequest.DistribRangeFacet.mergeFacetRangesFromShardResponse( newPivotFacet.rangeCounts, ranges); } newPivotFacet.childPivot = PivotFacetField.createFromListOfNamedLists(shardNumber, rb, newPivotFacet, childPivotData); return newPivotFacet; }