public DelegatingCollector getCollector()

in solr/core/src/java/org/apache/solr/search/CollapsingQParserPlugin.java [2056:2250]


    public DelegatingCollector getCollector(
        String collapseField,
        GroupHeadSelector groupHeadSelector,
        SortSpec sortSpec,
        int nullPolicy,
        String hint,
        boolean needsScores4Collapsing,
        boolean needsScores,
        int size,
        IntIntHashMap boostDocs,
        SolrIndexSearcher searcher)
        throws IOException {

      DocValuesProducer docValuesProducer = null;
      FunctionQuery funcQuery = null;

      // block collapsing logic is much simpler and uses less memory, but is only viable in specific
      // situations
      final boolean blockCollapse =
          (("_root_".equals(collapseField) || HINT_BLOCK.equals(hint))
              // because we currently handle all min/max cases using
              // AbstractBlockSortSpecCollector, we can't handle functions wrapping cscore()
              // (for the same reason cscore() isn't supported in 'sort' local param)
              && (!CollapseScore.wantsCScore(groupHeadSelector.selectorText))
              //
              && NullPolicy.COLLAPSE.getCode() != nullPolicy);
      if (HINT_BLOCK.equals(hint) && !blockCollapse) {
        log.debug(
            "Query specifies hint={} but other local params prevent the use block based collapse",
            HINT_BLOCK);
      }

      FieldType collapseFieldType = searcher.getSchema().getField(collapseField).getType();

      if (collapseFieldType instanceof StrField) {
        // if we are using blockCollapse, then there is no need to bother with TOP_FC
        if (HINT_TOP_FC.equals(hint) && !blockCollapse) {
          @SuppressWarnings("resource")
          final LeafReader uninvertingReader = getTopFieldCacheReader(searcher, collapseField);

          docValuesProducer =
              new EmptyDocValuesProducer() {
                @Override
                public SortedDocValues getSorted(FieldInfo ignored) throws IOException {
                  SortedDocValues values = uninvertingReader.getSortedDocValues(collapseField);
                  if (values != null) {
                    return values;
                  } else {
                    return DocValues.emptySorted();
                  }
                }
              };
        } else {
          docValuesProducer =
              new EmptyDocValuesProducer() {
                @Override
                public SortedDocValues getSorted(FieldInfo ignored) throws IOException {
                  return DocValues.getSorted(searcher.getSlowAtomicReader(), collapseField);
                }
              };
        }
      } else {
        if (HINT_TOP_FC.equals(hint)) {
          throw new SolrException(
              SolrException.ErrorCode.BAD_REQUEST,
              "top_fc hint is only supported when collapsing on String Fields");
        }
      }

      FieldType minMaxFieldType = null;
      if (GroupHeadSelectorType.MIN_MAX.contains(groupHeadSelector.type)) {
        final String text = groupHeadSelector.selectorText;
        if (!text.contains("(")) {
          minMaxFieldType = searcher.getSchema().getField(text).getType();
        } else {
          SolrParams params = new ModifiableSolrParams();
          try (SolrQueryRequest request = SolrQueryRequest.wrapSearcher(searcher, params)) {
            FunctionQParser functionQParser = new FunctionQParser(text, null, params, request);
            funcQuery = (FunctionQuery) functionQParser.parse();
          } catch (SyntaxError e) {
            throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, e);
          }
        }
      }

      int maxDoc = searcher.maxDoc();
      int leafCount = searcher.getTopReaderContext().leaves().size();

      SolrRequestInfo req = SolrRequestInfo.getRequestInfo();
      boolean collectElevatedDocsWhenCollapsing =
          req != null
              && req.getReq().getParams().getBool(COLLECT_ELEVATED_DOCS_WHEN_COLLAPSING, true);

      if (GroupHeadSelectorType.SCORE.equals(groupHeadSelector.type)) {

        if (collapseFieldType instanceof StrField) {
          if (blockCollapse) {
            return new BlockOrdScoreCollector(collapseField, nullPolicy, boostDocs);
          }
          return new OrdScoreCollector(
              maxDoc,
              leafCount,
              docValuesProducer,
              nullPolicy,
              boostDocs,
              searcher,
              collectElevatedDocsWhenCollapsing);

        } else if (isNumericCollapsible(collapseFieldType)) {
          if (blockCollapse) {
            return new BlockIntScoreCollector(collapseField, nullPolicy, boostDocs);
          }

          return new IntScoreCollector(
              maxDoc,
              leafCount,
              nullPolicy,
              size,
              collapseField,
              boostDocs,
              searcher,
              collectElevatedDocsWhenCollapsing);

        } else {
          throw new SolrException(
              SolrException.ErrorCode.BAD_REQUEST,
              "Collapsing field should be of either String, Int or Float type");
        }

      } else { // min, max, sort, etc.. something other then just "score"

        if (collapseFieldType instanceof StrField) {
          if (blockCollapse) {
            // NOTE: for now we don't worry about wether this is a sortSpec of min/max
            // groupHeadSelector, we use a "sort spec' based block collector unless/until there is
            // some (performance?) reason to specialize
            return new BlockOrdSortSpecCollector(
                collapseField,
                nullPolicy,
                boostDocs,
                BlockOrdSortSpecCollector.getSort(groupHeadSelector, sortSpec, funcQuery, searcher),
                needsScores || needsScores4Collapsing);
          }

          return new OrdFieldValueCollector(
              maxDoc,
              leafCount,
              docValuesProducer,
              nullPolicy,
              groupHeadSelector,
              sortSpec,
              needsScores4Collapsing,
              needsScores,
              minMaxFieldType,
              boostDocs,
              funcQuery,
              searcher,
              collectElevatedDocsWhenCollapsing);

        } else if (isNumericCollapsible(collapseFieldType)) {

          if (blockCollapse) {
            // NOTE: for now we don't worry about wether this is a sortSpec of min/max
            // groupHeadSelector, we use a "sort spec' based block collector unless/until there is
            // some (performance?) reason to specialize
            return new BlockIntSortSpecCollector(
                collapseField,
                nullPolicy,
                boostDocs,
                BlockOrdSortSpecCollector.getSort(groupHeadSelector, sortSpec, funcQuery, searcher),
                needsScores || needsScores4Collapsing);
          }

          return new IntFieldValueCollector(
              maxDoc,
              size,
              leafCount,
              nullPolicy,
              collapseField,
              groupHeadSelector,
              sortSpec,
              needsScores4Collapsing,
              needsScores,
              minMaxFieldType,
              boostDocs,
              funcQuery,
              searcher,
              collectElevatedDocsWhenCollapsing);
        } else {
          throw new SolrException(
              SolrException.ErrorCode.BAD_REQUEST,
              "Collapsing field should be of either String, Int or Float type");
        }
      }
    }