| package org.apache.lucene.facet.taxonomy; |
| |
| /* |
| * 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. |
| */ |
| |
| import java.io.IOException; |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.Comparator; |
| import java.util.List; |
| |
| import org.apache.lucene.facet.FacetResult; |
| import org.apache.lucene.facet.Facets; |
| import org.apache.lucene.facet.FacetsConfig.DimConfig; // javadocs |
| import org.apache.lucene.facet.FacetsConfig; |
| |
| /** Base class for all taxonomy-based facets impls. */ |
| public abstract class TaxonomyFacets extends Facets { |
| |
| private static final Comparator<FacetResult> BY_VALUE_THEN_DIM = new Comparator<FacetResult>() { |
| @Override |
| public int compare(FacetResult a, FacetResult b) { |
| if (a.value.doubleValue() > b.value.doubleValue()) { |
| return -1; |
| } else if (b.value.doubleValue() > a.value.doubleValue()) { |
| return 1; |
| } else { |
| return a.dim.compareTo(b.dim); |
| } |
| } |
| }; |
| |
| /** Index field name provided to the constructor. */ |
| protected final String indexFieldName; |
| |
| /** {@code TaxonomyReader} provided to the constructor. */ |
| protected final TaxonomyReader taxoReader; |
| |
| /** {@code FacetsConfig} provided to the constructor. */ |
| protected final FacetsConfig config; |
| |
| /** Maps parent ordinal to its child, or -1 if the parent |
| * is childless. */ |
| protected final int[] children; |
| |
| /** Maps an ordinal to its sibling, or -1 if there is no |
| * sibling. */ |
| protected final int[] siblings; |
| |
| /** Sole constructor. */ |
| protected TaxonomyFacets(String indexFieldName, TaxonomyReader taxoReader, FacetsConfig config) throws IOException { |
| this.indexFieldName = indexFieldName; |
| this.taxoReader = taxoReader; |
| this.config = config; |
| ParallelTaxonomyArrays pta = taxoReader.getParallelTaxonomyArrays(); |
| children = pta.children(); |
| siblings = pta.siblings(); |
| } |
| |
| /** Throws {@code IllegalArgumentException} if the |
| * dimension is not recognized. Otherwise, returns the |
| * {@link DimConfig} for this dimension. */ |
| protected FacetsConfig.DimConfig verifyDim(String dim) { |
| FacetsConfig.DimConfig dimConfig = config.getDimConfig(dim); |
| if (!dimConfig.indexFieldName.equals(indexFieldName)) { |
| throw new IllegalArgumentException("dimension \"" + dim + "\" was not indexed into field \"" + indexFieldName); |
| } |
| return dimConfig; |
| } |
| |
| @Override |
| public List<FacetResult> getAllDims(int topN) throws IOException { |
| int ord = children[TaxonomyReader.ROOT_ORDINAL]; |
| List<FacetResult> results = new ArrayList<FacetResult>(); |
| while (ord != TaxonomyReader.INVALID_ORDINAL) { |
| String dim = taxoReader.getPath(ord).components[0]; |
| FacetsConfig.DimConfig dimConfig = config.getDimConfig(dim); |
| if (dimConfig.indexFieldName.equals(indexFieldName)) { |
| FacetResult result = getTopChildren(topN, dim); |
| if (result != null) { |
| results.add(result); |
| } |
| } |
| ord = siblings[ord]; |
| } |
| |
| // Sort by highest value, tie break by dim: |
| Collections.sort(results, BY_VALUE_THEN_DIM); |
| return results; |
| } |
| |
| } |