Search code examples
solrelasticsearchlucenetaxonomyfacet

Lucene use taxonomy and DocValues facets together


There are many examples of the use of facets based on the taxonomy index and on DocValues. But I need use as a hierarchy of categories (taxonomy) and Range queries (NumericDocValuesField) together. For example DrillSideways :

  DrillSideways ds = new DrillSideways (searcher, config, taxoReader);
  DrillSideways.DrillSidewaysResult result = ds.search (q, topScoreDocCollector);

The second parameter of ds.search() is TopScoreDocCollector.

FacetsCollector created inside ds.search() and not possible to pass this collector to ds.search(). Pass MultiCollector.wrap (FacetsCollector, TopScoreDocCollector) as second parameter in ds.search() is not correct(?). However FacetsCollector need to build facets that are not available in the taxonomy index:

 Facets facetsTime = new LongRangeFacetCounts (..., FacetsCollector, ...);
 facetsTime.getTopChildren (...);

Also list result.facets contain null value, which refers to DocValues ​​facet.

Maybe you have a working example how use taxonomy and DocValues ​​facets in DrillSideways together.


Solution

  • DrillSideways assumes that you use either TaxonomyFacets or SortedSetDocValuesFacets exclusively. If this is not the case, you can subclass DrillSideways and override the buildFacetsResult method to build the final Facets however you like. You will get the FacetsCollector for the DrillDownQuery and two arrays with the sideways FacetCollectors and dims, for every dim you have added to the DrissSideways.

    Here is an example:

    public class MyDrillSideways extends DrillSideways {
    
      public MyDrillSideways(IndexSearcher searcher, FacetsConfig config, TaxonomyReader taxoReader) {
        super(searcher, config, taxoReader);
      }
    
      @Override
      protected Facets buildFacetsResult(FacetsCollector drillDowns, FacetsCollector[] drillSideways, String[] drillSidewaysDims) throws IOException {
    
        String longRangeFacetDim = "mySpecialLongRangeDim";
        Facets drillDownFacets = new FastTaxonomyFacetCounts(taxoReader, config, drillDowns);
    
        boolean foundLongRangeInDrillSideways = false;
        Map<String, Facets> drillSidewaysFacets = new HashMap<>();
        if (drillSideways != null) {
          for (int i = 0; i < drillSideways.length; i++) {
            String sidewaysDim = drillSidewaysDims[i];
            FacetsCollector drillSideway = drillSideways[i];
    
            Facets sidewaysFacets;
            if (sidewaysDim.equals(longRangeFacetDim)) {
              foundLongRangeInDrillSideways = true;
              sidewaysFacets = new LongRangeFacetCounts(...,drillSideway,...);
            } else {
              sidewaysFacets = new FastTaxonomyFacetCounts(taxoReader, config, drillSideway);
            }
            drillSidewaysFacets.put(sidewaysDim, sidewaysFacets);
          }
        }
    
        if (!foundLongRangeInDrillSideways) {
          Facets facetsTime = new LongRangeFacetCounts(..., FacetsCollector, ...);
          drillSidewaysFacets.put(longRangeFacetDim, facetsTime);
        }
    
        return new MultiFacets(drillSidewaysFacets, drillDownFacets);
      }
    }