This is an automated email from the ASF dual-hosted git repository.

mdrob pushed a commit to branch branch_9_0
in repository https://gitbox.apache.org/repos/asf/solr.git


The following commit(s) were added to refs/heads/branch_9_0 by this push:
     new db7ffce  SOLR-12336 Remove Filter from Solr (#529)
db7ffce is described below

commit db7ffcecd6e8f4e8f4cae18d3839d4c0998633f4
Author: Collins Abanda <[email protected]>
AuthorDate: Fri Feb 11 16:21:56 2022 -0600

    SOLR-12336 Remove Filter from Solr (#529)
    
    Includes:
    
    * Remove Filter from Solr and replace with Lucene Query
    * Remove SolrConstantScoreQuery and all its usages
    * SOLR-15257 Add DocSetQuery to replace some usage of Filter
    
    (cherry picked from commit ef4e7e124bdf55b12210052d8b2b5ff5ce447253)
    (cherry picked from commit 544ac12370d6caf9ccc47e557d7743fdcef9784a)
---
 solr/CHANGES.txt                                   |   6 +
 .../apache/solr/parser/SolrQueryParserBase.java    |   3 +-
 .../java/org/apache/solr/query/FilterQuery.java    |   6 +-
 .../java/org/apache/solr/request/SimpleFacets.java |   6 +-
 .../src/java/org/apache/solr/search/BitDocSet.java |  72 +---------
 .../apache/solr/search/BitsFilteredDocIdSet.java   |  62 ---------
 .../src/java/org/apache/solr/search/DocSet.java    |   8 +-
 .../java/org/apache/solr/search/DocSetQuery.java   |  99 ++++++++++++++
 .../java/org/apache/solr/search/DocSetUtil.java    |   2 +-
 .../src/java/org/apache/solr/search/Filter.java    | 146 ---------------------
 .../org/apache/solr/search/FunctionRangeQuery.java |  44 ++++++-
 .../src/java/org/apache/solr/search/RankQuery.java |   1 -
 .../apache/solr/search/SolrConstantScoreQuery.java | 138 -------------------
 .../java/org/apache/solr/search/SolrFilter.java    |  46 -------
 .../org/apache/solr/search/SolrIndexSearcher.java  |  10 +-
 .../org/apache/solr/search/SortedIntDocSet.java    |  47 +------
 .../org/apache/solr/search/facet/FacetRequest.java |  31 ++---
 .../search/function/ValueSourceRangeFilter.java    |  80 ++++++-----
 .../test/org/apache/solr/search/TestDocSet.java    |  59 +++++----
 .../apache/solr/search/TestFilteredDocIdSet.java   |  79 +++++++----
 .../src/test/org/apache/solr/search/TestSort.java  |  38 ++++--
 .../org/apache/solr/analytics/AnalyticsDriver.java |  16 +--
 .../solr/analytics/AnalyticsGroupingManager.java   |   5 +-
 .../solr/analytics/AnalyticsRequestManager.java    |   4 +-
 .../analytics/facet/AbstractSolrQueryFacet.java    |   5 +-
 .../apache/solr/analytics/facet/QueryFacet.java    |   3 +-
 .../apache/solr/analytics/facet/RangeFacet.java    |   3 +-
 .../org/apache/solr/handler/AnalyticsHandler.java  |   4 +-
 .../solr/handler/component/AnalyticsComponent.java |   2 +-
 .../org/apache/solr/ltr/feature/SolrFeature.java   |   2 +-
 .../pages/major-changes-in-solr-9.adoc             |   4 +-
 31 files changed, 367 insertions(+), 664 deletions(-)

diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index c51c64c..ab34fe1 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -214,6 +214,12 @@ when told to. The admin UI now tells it to. (Nazerke 
Seidan, David Smiley)
 * SOLR-15209: The old LegacyAssignStrategy has been refactored into the 
SimplePlacementPlugin. This is still the default
   placement policy for Solr. (Houston Putman, Ilan Ginzburg)
 
+* SOLR-15257: Replace DocSet.getTopFilter with DocSet.makeQuery. Create 
DocSetQuery which is a Query
+  and DocSetProducer. (Collins Abanda, Mike Drob, Tim Potter, David Smiley, 
Michael Gibney)
+
+* SOLR-12336: Remove Filter, SolrFilter and SolrConstantScoreQuery. Filter no 
longer has a need to exist due to multiple JIRA issues,
+  implemented by a number of issues. With Filter going away, there is no 
longer need for SolrConstantScoreQuery. (Collins Abanda, Mike Drob, Tim Potter, 
David Smiley, Michael Gibney)
+
 * SOLR-14916: Add split parameter to timeseries Streaming Expression (Joel 
Bernstein)
 
 * SOLR-14686: Logs: Removed the "[corename]" prefix of some SolrCore logs that 
has become redundant
diff --git a/solr/core/src/java/org/apache/solr/parser/SolrQueryParserBase.java 
b/solr/core/src/java/org/apache/solr/parser/SolrQueryParserBase.java
index 54b0574..00de69f 100644
--- a/solr/core/src/java/org/apache/solr/parser/SolrQueryParserBase.java
+++ b/solr/core/src/java/org/apache/solr/parser/SolrQueryParserBase.java
@@ -65,7 +65,6 @@ import org.apache.solr.schema.SchemaField;
 import org.apache.solr.schema.TextField;
 import org.apache.solr.search.QParser;
 import org.apache.solr.search.QueryUtils;
-import org.apache.solr.search.SolrConstantScoreQuery;
 import org.apache.solr.search.SyntaxError;
 import org.apache.lucene.queryparser.charstream.CharStream;
 import org.apache.lucene.queryparser.charstream.FastCharStream;
@@ -864,7 +863,7 @@ public abstract class SolrQueryParserBase extends 
QueryBuilder {
       // syntax looks like foo:x^=3
       float val = Float.parseFloat(boost.image.substring(1));
       Query newQ = q;
-      if (q instanceof ConstantScoreQuery || q instanceof 
SolrConstantScoreQuery) {
+      if (q instanceof ConstantScoreQuery) {
         // skip
       } else {
         newQ = new ConstantScoreQuery( rawToNormal(q) );
diff --git a/solr/core/src/java/org/apache/solr/query/FilterQuery.java 
b/solr/core/src/java/org/apache/solr/query/FilterQuery.java
index 4df704e..7938c2a 100644
--- a/solr/core/src/java/org/apache/solr/query/FilterQuery.java
+++ b/solr/core/src/java/org/apache/solr/query/FilterQuery.java
@@ -19,7 +19,6 @@ package org.apache.solr.query;
 import java.io.IOException;
 
 import org.apache.lucene.index.IndexReader;
-import org.apache.lucene.search.BoostQuery;
 import org.apache.lucene.search.ConstantScoreQuery;
 import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.MatchNoDocsQuery;
@@ -29,7 +28,6 @@ import org.apache.lucene.search.ScoreMode;
 import org.apache.lucene.search.Weight;
 import org.apache.solr.search.DocSet;
 import org.apache.solr.search.ExtendedQueryBase;
-import org.apache.solr.search.SolrConstantScoreQuery;
 import org.apache.solr.search.SolrIndexSearcher;
 
 public class FilterQuery extends ExtendedQueryBase {
@@ -89,13 +87,13 @@ public class FilterQuery extends ExtendedQueryBase {
 
     if (!(searcher instanceof SolrIndexSearcher)) {
       // delete-by-query won't have SolrIndexSearcher
-      return new BoostQuery(new ConstantScoreQuery(q), 
0).createWeight(searcher, scoreMode, 1f);
+      return new ConstantScoreQuery(q).createWeight(searcher, scoreMode, 1f);
     }
 
     SolrIndexSearcher solrSearcher = (SolrIndexSearcher)searcher;
     DocSet docs = solrSearcher.getDocSet(q);
     // reqInfo.addCloseHook(docs);  // needed for off-heap refcounting
 
-    return new BoostQuery(new SolrConstantScoreQuery(docs.getTopFilter()), 
0).createWeight(searcher, scoreMode, 1f);
+    return docs.makeQuery().createWeight(searcher, scoreMode, 1f);
   }
 }
diff --git a/solr/core/src/java/org/apache/solr/request/SimpleFacets.java 
b/solr/core/src/java/org/apache/solr/request/SimpleFacets.java
index 099000a..e3d6bb3 100644
--- a/solr/core/src/java/org/apache/solr/request/SimpleFacets.java
+++ b/solr/core/src/java/org/apache/solr/request/SimpleFacets.java
@@ -268,7 +268,7 @@ public class SimpleFacets {
         return base;
       }
       AllGroupHeadsCollector<?> allGroupHeadsCollector = 
grouping.getCommands().get(0).createAllGroupCollector();
-      searcher.search(base.getTopFilter(), allGroupHeadsCollector);
+      searcher.search(base.makeQuery(), allGroupHeadsCollector);
       return new 
BitDocSet(allGroupHeadsCollector.retrieveGroupHeads(searcher.maxDoc()));
     } else {
       return base;
@@ -334,7 +334,7 @@ public class SimpleFacets {
     }
 
     AllGroupsCollector<?> collector = new AllGroupsCollector<>(new 
TermGroupSelector(groupField));
-    searcher.search(QueryUtils.combineQueryAndFilter(facetQuery, 
docSet.getTopFilter()), collector);
+    searcher.search(QueryUtils.combineQueryAndFilter(facetQuery, 
docSet.makeQuery()), collector);
     return collector.getGroupCount();
   }
 
@@ -721,7 +721,7 @@ public class SimpleFacets {
     Collector groupWrapper = getNumericHidingWrapper(groupField, collector);
     Collector fieldWrapper = getNumericHidingWrapper(field, groupWrapper);
     // When GroupFacetCollector can handle numerics we can remove the wrapped 
collectors
-    searcher.search(base.getTopFilter(), fieldWrapper);
+    searcher.search(base.makeQuery(), fieldWrapper);
     
     boolean orderByCount = sort.equals(FacetParams.FACET_SORT_COUNT) || 
sort.equals(FacetParams.FACET_SORT_COUNT_LEGACY);
     TermGroupFacetCollector.GroupedFacetResult result 
diff --git a/solr/core/src/java/org/apache/solr/search/BitDocSet.java 
b/solr/core/src/java/org/apache/solr/search/BitDocSet.java
index 6597659..49a08b4 100644
--- a/solr/core/src/java/org/apache/solr/search/BitDocSet.java
+++ b/solr/core/src/java/org/apache/solr/search/BitDocSet.java
@@ -18,14 +18,10 @@ package org.apache.solr.search;
 
 import java.util.Collection;
 import java.util.Collections;
-import java.util.Objects;
-
 import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.search.DocIdSet;
 import org.apache.lucene.search.DocIdSetIterator;
 import org.apache.lucene.util.Accountable;
 import org.apache.lucene.util.BitSetIterator;
-import org.apache.lucene.util.Bits;
 import org.apache.lucene.util.FixedBitSet;
 import org.apache.lucene.util.RamUsageEstimator;
 
@@ -311,72 +307,8 @@ public class BitDocSet extends DocSet {
     };
   }
 
-  @Override
-  public Filter getTopFilter() {
-    // TODO: if cardinality isn't cached, do a quick measure of sparseness
-    // and return null from bits() if too sparse.
-
-    return new Filter() {
-      final FixedBitSet bs = bits;
-
-      @Override
-      public DocIdSet getDocIdSet(final LeafReaderContext context, final Bits 
acceptDocs) {
-        // all Solr DocSets that are used as filters only include live docs
-        final Bits acceptDocs2 = acceptDocs == null ? null : 
(context.reader().getLiveDocs() == acceptDocs ? null : acceptDocs);
-
-        return BitsFilteredDocIdSet.wrap(new DocIdSet() {
-          @Override
-          public DocIdSetIterator iterator() {
-            return BitDocSet.this.iterator(context);
-          }
-
-          @Override
-          public long ramBytesUsed() {
-            return BitDocSet.this.ramBytesUsed();
-          }
-
-          @Override
-          public Bits bits() {
-            if (context.isTopLevel) {
-              return bits;
-            }
-
-            final int base = context.docBase;
-            final int length = context.reader().maxDoc();
-            final FixedBitSet bs = bits;
-
-            return new Bits() {
-              @Override
-              public boolean get(int index) {
-                return bs.get(index + base);
-              }
-
-              @Override
-              public int length() {
-                return length;
-              }
-            };
-          }
-
-        }, acceptDocs2);
-      }
-
-      @Override
-      public String toString(String field) {
-        return "BitSetDocTopFilter";
-      }
-
-      @Override
-      public boolean equals(Object other) {
-        return sameClassAs(other) &&
-               Objects.equals(bs, getClass().cast(other).bs);
-      }
-      
-      @Override
-      public int hashCode() {
-        return classHash() * 31 + bs.hashCode();
-      }
-    };
+  public DocSetQuery makeQuery() {
+    return new DocSetQuery(this);
   }
 
   @Override
diff --git 
a/solr/core/src/java/org/apache/solr/search/BitsFilteredDocIdSet.java 
b/solr/core/src/java/org/apache/solr/search/BitsFilteredDocIdSet.java
deleted file mode 100644
index df38fe8..0000000
--- a/solr/core/src/java/org/apache/solr/search/BitsFilteredDocIdSet.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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.
- */
-package org.apache.solr.search;
-
-import java.util.Objects;
-
-import org.apache.lucene.search.DocIdSet;
-import org.apache.lucene.util.Bits;
-
-/**
- * This implementation supplies a filtered DocIdSet, that excludes all
- * docids which are not in a Bits instance. This is especially useful in
- * {@link org.apache.solr.search.Filter} to apply the {@code acceptDocs}
- * passed to {@code getDocIdSet()} before returning the final DocIdSet.
- *
- * @see DocIdSet
- * @see org.apache.solr.search.Filter
- */
-public final class BitsFilteredDocIdSet extends FilteredDocIdSet {
-
-  private final Bits acceptDocs;
-  
-  /**
-   * Convenience wrapper method: If {@code acceptDocs == null} it returns the 
original set without wrapping.
-   * @param set Underlying DocIdSet. If {@code null}, this method returns 
{@code null}
-   * @param acceptDocs Allowed docs, all docids not in this set will not be 
returned by this DocIdSet.
-   * If {@code null}, this method returns the original set without wrapping.
-   */
-  public static DocIdSet wrap(DocIdSet set, Bits acceptDocs) {
-    return (set == null || acceptDocs == null) ? set : new 
BitsFilteredDocIdSet(set, acceptDocs);
-  }
-  
-  /**
-   * Constructor.
-   * @param innerSet Underlying DocIdSet
-   * @param acceptDocs Allowed docs, all docids not in this set will not be 
returned by this DocIdSet
-   */
-  public BitsFilteredDocIdSet(DocIdSet innerSet, Bits acceptDocs) {
-    super(innerSet);
-    this.acceptDocs = Objects.requireNonNull(acceptDocs, "Bits must not be 
null");
-  }
-
-  @Override
-  protected boolean match(int docid) {
-    return acceptDocs.get(docid);
-  }
-
-}
diff --git a/solr/core/src/java/org/apache/solr/search/DocSet.java 
b/solr/core/src/java/org/apache/solr/search/DocSet.java
index 157f67f..2d2afca 100644
--- a/solr/core/src/java/org/apache/solr/search/DocSet.java
+++ b/solr/core/src/java/org/apache/solr/search/DocSet.java
@@ -18,6 +18,7 @@ package org.apache.solr.search;
 
 import org.apache.lucene.index.LeafReaderContext;
 import org.apache.lucene.search.DocIdSetIterator;
+import org.apache.lucene.search.Query;
 import org.apache.lucene.util.Accountable;
 import org.apache.lucene.util.Bits;
 import org.apache.lucene.util.FixedBitSet;
@@ -117,11 +118,12 @@ public abstract class DocSet implements Accountable, 
Cloneable /* extends Collec
   }
 
   /**
-   * Returns a Filter for use in Lucene search methods, assuming this DocSet
+   * Returns a constant scoring Query for use in Lucene search methods, 
assuming this DocSet
    * was generated from the top-level MultiReader that the Lucene search
-   * methods will be invoked with.
+   * methods will be invoked with. DocSets, and thus this query, do not
+   * match deleted docs.
    */
-  public abstract Filter getTopFilter();
+  public abstract Query makeQuery();
 
   /**
    * Adds all the docs from this set to the target. The target should be
diff --git a/solr/core/src/java/org/apache/solr/search/DocSetQuery.java 
b/solr/core/src/java/org/apache/solr/search/DocSetQuery.java
new file mode 100644
index 0000000..e53ac0e
--- /dev/null
+++ b/solr/core/src/java/org/apache/solr/search/DocSetQuery.java
@@ -0,0 +1,99 @@
+/*
+ * 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.
+ */
+package org.apache.solr.search;
+
+import org.apache.lucene.index.LeafReaderContext;
+import org.apache.lucene.search.ConstantScoreScorer;
+import org.apache.lucene.search.ConstantScoreWeight;
+import org.apache.lucene.search.DocIdSetIterator;
+import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
+import org.apache.lucene.search.ScoreMode;
+import org.apache.lucene.search.Scorer;
+import org.apache.lucene.search.Weight;
+
+import java.io.IOException;
+import java.util.Objects;
+
+/**
+ * A class that accesses Queries based on a DocSet
+ *
+ * Refer SOLR-15257
+ */
+public class DocSetQuery extends Query implements DocSetProducer{
+    private final DocSet docSet;
+
+    public DocSetQuery(DocSet docSet) {
+        super();
+        this.docSet = docSet;
+    }
+
+    @Override
+    public String toString(String field) {
+        return "DocSetQuery(" + field + ")";
+    }
+
+    @Override
+    public void visit(QueryVisitor visitor) {
+        visitor.visitLeaf(this);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return sameClassAs(obj) && equalsTo(getClass().cast(obj));
+    }
+
+    private boolean equalsTo(DocSetQuery other) {
+        return Objects.equals(docSet, other.docSet);
+    }
+
+    @Override
+    public int hashCode() {
+        return classHash() * 31 + (docSet != null ? docSet.hashCode() : 0);
+    }
+
+    /**
+     * @param searcher is not used because we already have a DocSet created in 
DocSetQuery
+     * @return the DocSet created in DocSetQuery
+     */
+    @Override
+    public DocSet createDocSet(SolrIndexSearcher searcher) throws IOException {
+        return docSet;
+    }
+
+    @Override
+    public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, 
float boost) throws IOException {
+        //This should probably use the provided boost as scorer. However, that 
causes
+        // TestSolrQueryParser.testFilter to fail.
+        return new ConstantScoreWeight(this, 0) {
+            @Override
+            public Scorer scorer(LeafReaderContext context) throws IOException 
{
+                DocIdSetIterator disi = docSet.iterator(context);
+                if (disi == null) {
+                    return null;
+                }
+                return new ConstantScoreScorer(this, score(), scoreMode, disi);
+            }
+
+            @Override
+            public boolean isCacheable(LeafReaderContext ctx) {
+                return true;
+            }
+        };
+    }
+}
diff --git a/solr/core/src/java/org/apache/solr/search/DocSetUtil.java 
b/solr/core/src/java/org/apache/solr/search/DocSetUtil.java
index 3feac40..74b4aed 100644
--- a/solr/core/src/java/org/apache/solr/search/DocSetUtil.java
+++ b/solr/core/src/java/org/apache/solr/search/DocSetUtil.java
@@ -118,7 +118,7 @@ public class DocSetUtil {
   public static DocSet createDocSet(SolrIndexSearcher searcher, Query query, 
DocSet filter) throws IOException {
 
     if (filter != null) {
-      query = QueryUtils.combineQueryAndFilter(query, filter.getTopFilter());
+      query = QueryUtils.combineQueryAndFilter(query, filter.makeQuery());
     }
 
     if (query instanceof TermQuery) {
diff --git a/solr/core/src/java/org/apache/solr/search/Filter.java 
b/solr/core/src/java/org/apache/solr/search/Filter.java
deleted file mode 100644
index bd70991..0000000
--- a/solr/core/src/java/org/apache/solr/search/Filter.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * 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.
- */
-package org.apache.solr.search;
-
-import java.io.IOException;
-
-import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.search.ConstantScoreScorer;
-import org.apache.lucene.search.DocIdSet;
-import org.apache.lucene.search.DocIdSetIterator;
-import org.apache.lucene.search.Explanation;
-import org.apache.lucene.search.IndexSearcher;
-import org.apache.lucene.search.Query;
-import org.apache.lucene.search.QueryVisitor;
-import org.apache.lucene.search.ScoreMode;
-import org.apache.lucene.search.Scorer;
-import org.apache.lucene.search.TwoPhaseIterator;
-import org.apache.lucene.search.Weight;
-import org.apache.lucene.util.Bits;
-
-/**
- *  Convenient base class for building queries that only perform matching, but
- *  no scoring. The scorer produced by such queries always returns 0 as score.
- */
-public abstract class Filter extends Query {
-
-  private final boolean applyLazily;
-
-  /** Filter constructor. When {@code applyLazily} is true and the produced
-   *  {@link DocIdSet}s support {@link DocIdSet#bits() random-access}, Lucene
-   *  will only apply this filter after other clauses. */
-  protected Filter(boolean applyLazily) {
-    this.applyLazily = applyLazily;
-  }
-
-  /** Default Filter constructor that will use the
-   *  {@link DocIdSet#iterator() doc id set iterator} when consumed through
-   *  the {@link Query} API. */
-  protected Filter() {
-    this(false);
-  }
-
-  /**
-   * Creates a {@link DocIdSet} enumerating the documents that should be
-   * permitted in search results. <b>NOTE:</b> null can be
-   * returned if no documents are accepted by this Filter.
-   * <p>
-   * Note: This method will be called once per segment in
-   * the index during searching.  The returned {@link DocIdSet}
-   * must refer to document IDs for that segment, not for
-   * the top-level reader.
-   *
-   * @param context a {@link org.apache.lucene.index.LeafReaderContext} 
instance opened on the index currently
-   *         searched on. Note, it is likely that the provided reader info 
does not
-   *         represent the whole underlying index i.e. if the index has more 
than
-   *         one segment the given reader only represents a single segment.
-   *         The provided context is always an atomic context, so you can call
-   *         {@link org.apache.lucene.index.LeafReader#terms(String)}
-   *         on the context's reader, for example.
-   *
-   * @param acceptDocs
-   *          Bits that represent the allowable docs to match (typically 
deleted docs
-   *          but possibly filtering other documents)
-   *
-   * @return a DocIdSet that provides the documents which should be permitted 
or
-   *         prohibited in search results. <b>NOTE:</b> <code>null</code> 
should be returned if
-   *         the filter doesn't accept any documents otherwise internal 
optimization might not apply
-   *         in the case an <i>empty</i> {@link DocIdSet} is returned.
-   */
-  public abstract DocIdSet getDocIdSet(LeafReaderContext context, Bits 
acceptDocs) throws IOException;
-
-  //
-  // Query compatibility
-  //
-
-  @Override
-  public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, 
float boost) {
-    return new Weight(this) {
-
-      @Override
-      public Explanation explain(LeafReaderContext context, int doc) throws 
IOException {
-        final Scorer scorer = scorer(context);
-        final boolean match = (scorer != null && 
scorer.iterator().advance(doc) == doc);
-        if (match) {
-          assert scorer.score() == 0f;
-          return Explanation.match(0f, "Match on id " + doc);
-        } else {
-          return Explanation.match(0f, "No match on id " + doc);
-        }
-      }
-
-      @Override
-      public Scorer scorer(LeafReaderContext context) throws IOException {
-        final DocIdSet set = getDocIdSet(context, null);
-        if (set == null) {
-          return null;
-        }
-        if (applyLazily && set.bits() != null) {
-          final Bits bits = set.bits();
-          final DocIdSetIterator approximation = 
DocIdSetIterator.all(context.reader().maxDoc());
-          final TwoPhaseIterator twoPhase = new 
TwoPhaseIterator(approximation) {
-            @Override
-            public boolean matches() throws IOException {
-              return bits.get(approximation.docID());
-            }
-
-            @Override
-            public float matchCost() {
-              return 10; // TODO use cost of bits.get()
-            }
-          };
-          return new ConstantScoreScorer(this, 0f, scoreMode, twoPhase);
-        }
-        final DocIdSetIterator iterator = set.iterator();
-        if (iterator == null) {
-          return null;
-        }
-        return new ConstantScoreScorer(this, 0f, scoreMode, iterator);
-      }
-
-      @Override
-      public boolean isCacheable(LeafReaderContext ctx) {
-        return false;
-      }
-    };
-  }
-
-  @Override
-  public void visit(QueryVisitor visitor) {
-    visitor.visitLeaf(this);
-  }
-}
diff --git a/solr/core/src/java/org/apache/solr/search/FunctionRangeQuery.java 
b/solr/core/src/java/org/apache/solr/search/FunctionRangeQuery.java
index 6b8fdaa..c458db9 100644
--- a/solr/core/src/java/org/apache/solr/search/FunctionRangeQuery.java
+++ b/solr/core/src/java/org/apache/solr/search/FunctionRangeQuery.java
@@ -18,31 +18,44 @@ package org.apache.solr.search;
 
 import java.io.IOException;
 import java.util.Map;
+import java.util.Objects;
 
 import org.apache.lucene.index.LeafReaderContext;
 import org.apache.lucene.queries.function.FunctionValues;
 import org.apache.lucene.queries.function.ValueSource;
 import org.apache.lucene.queries.function.ValueSourceScorer;
 import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.QueryVisitor;
 import org.apache.lucene.search.ScoreMode;
 import org.apache.lucene.search.Weight;
+import org.apache.solr.common.SolrException;
 import org.apache.solr.search.function.ValueSourceRangeFilter;
 
-// This class works as either a normal constant score query, or as a 
PostFilter using a collector
-public class FunctionRangeQuery extends SolrConstantScoreQuery implements 
PostFilter {
+// This class works as either an ExtendedQuery, or as a PostFilter using a 
collector
+public class FunctionRangeQuery extends ExtendedQueryBase implements 
PostFilter {
 
   final ValueSourceRangeFilter rangeFilt;
 
   public FunctionRangeQuery(ValueSourceRangeFilter filter) {
-    super(filter);
+    super();
     this.rangeFilt = filter;
-    this.cost = 100; // default behavior should be PostFiltering
+    super.setCost(100); // default behavior should be PostFiltering
+  }
+
+  @Override
+  public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, 
float boost) throws IOException {
+    return rangeFilt.createWeight(searcher, scoreMode, boost);
   }
 
   @Override
   public DelegatingCollector getFilterCollector(IndexSearcher searcher) {
     Map<Object,Object> fcontext = ValueSource.newContext(searcher);
-    Weight weight = rangeFilt.createWeight(searcher, ScoreMode.COMPLETE, 1);
+    Weight weight = null;
+    try {
+      weight = rangeFilt.createWeight(searcher, ScoreMode.COMPLETE, 1);
+    } catch (IOException e) {
+      throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, e);
+    }
     return new FunctionRangeCollector(fcontext, weight);
   }
 
@@ -73,4 +86,25 @@ public class FunctionRangeQuery extends 
SolrConstantScoreQuery implements PostFi
       scorer = dv.getRangeScorer(weight, context, rangeFilt.getLowerVal(), 
rangeFilt.getUpperVal(), rangeFilt.isIncludeLower(), 
rangeFilt.isIncludeUpper());
     }
   }
+
+  @Override
+  public String toString(String field) {
+    return "FunctionRangeQuery(" + field + ")";
+  }
+
+  @Override
+  public void visit(QueryVisitor visitor) {
+    visitor.visitLeaf(this);
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    return sameClassAs(obj) &&
+            Objects.equals(rangeFilt, ((FunctionRangeQuery) obj).rangeFilt);
+  }
+
+  @Override
+  public int hashCode() {
+    return 31 * classHash() + rangeFilt.hashCode();
+  }
 }
diff --git a/solr/core/src/java/org/apache/solr/search/RankQuery.java 
b/solr/core/src/java/org/apache/solr/search/RankQuery.java
index a72667e..bcc132a 100644
--- a/solr/core/src/java/org/apache/solr/search/RankQuery.java
+++ b/solr/core/src/java/org/apache/solr/search/RankQuery.java
@@ -33,5 +33,4 @@ public abstract class RankQuery extends ExtendedQueryBase {
   public abstract TopDocsCollector<ScoreDoc> getTopDocsCollector(int len, 
QueryCommand cmd, IndexSearcher searcher) throws IOException;
   public abstract MergeStrategy getMergeStrategy();
   public abstract RankQuery wrap(Query mainQuery);
-
 }
diff --git 
a/solr/core/src/java/org/apache/solr/search/SolrConstantScoreQuery.java 
b/solr/core/src/java/org/apache/solr/search/SolrConstantScoreQuery.java
deleted file mode 100644
index e21afe7..0000000
--- a/solr/core/src/java/org/apache/solr/search/SolrConstantScoreQuery.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * 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.
- */
-package org.apache.solr.search;
-
-import java.io.IOException;
-import java.util.Map;
-import java.util.Objects;
-
-import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.queries.function.ValueSource;
-import org.apache.lucene.search.ConstantScoreScorer;
-import org.apache.lucene.search.ConstantScoreWeight;
-import org.apache.lucene.search.DocIdSet;
-import org.apache.lucene.search.DocIdSetIterator;
-import org.apache.lucene.search.IndexSearcher;
-import org.apache.lucene.search.Query;
-import org.apache.lucene.search.QueryVisitor;
-import org.apache.lucene.search.ScoreMode;
-import org.apache.lucene.search.Scorer;
-import org.apache.lucene.search.Weight;
-
-/**
- * A query that wraps a filter and simply returns a constant score equal to the
- * query boost for every document in the filter.   This Solr extension also 
supports
- * weighting of a SolrFilter.
- *
- * Experimental and subject to change.
- */
-public class SolrConstantScoreQuery extends Query implements ExtendedQuery {
-  private final Filter filter;
-  boolean cache = true;  // cache by default
-  int cost;
-
-  public SolrConstantScoreQuery(Filter filter) {
-    this.filter = filter;
-  }
-
-  /** Returns the encapsulated filter */
-  public Filter getFilter() {
-    return filter;
-  }
-
-  @Override
-  public void setCache(boolean cache) {
-    this.cache = cache;
-  }
-
-  @Override
-  public boolean getCache() {
-    return cache;
-  }
-
-  @Override
-  public void setCost(int cost) {
-    this.cost = cost;
-  }
-
-  @Override
-  public int getCost() {
-    return cost;
-  }
-
-  protected class ConstantWeight extends ConstantScoreWeight {
-    private Map<Object,Object> context;
-    private ScoreMode scoreMode;
-
-    public ConstantWeight(IndexSearcher searcher, ScoreMode scoreMode, float 
boost) throws IOException {
-      super(SolrConstantScoreQuery.this, boost);
-      this.scoreMode = scoreMode;
-      this.context = ValueSource.newContext(searcher);
-      if (filter instanceof SolrFilter)
-        ((SolrFilter)filter).createWeight(context, searcher);
-    }
-
-    @Override
-    public Scorer scorer(LeafReaderContext context) throws IOException {
-      DocIdSet docIdSet = filter instanceof SolrFilter ? 
((SolrFilter)filter).getDocIdSet(this.context, context, null) : 
filter.getDocIdSet(context, null);
-      if (docIdSet == null) {
-        return null;
-      }
-      DocIdSetIterator iterator = docIdSet.iterator();
-      if (iterator == null) {
-        return null;
-      }
-      return new ConstantScoreScorer(this, score(), scoreMode, iterator);
-    }
-
-    @Override
-    public boolean isCacheable(LeafReaderContext ctx) {
-      return false;
-    }
-
-  }
-
-  @Override
-  public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, 
float boost) throws IOException {
-    return new SolrConstantScoreQuery.ConstantWeight(searcher, scoreMode, 
boost);
-  }
-
-  /** Prints a user-readable version of this query. */
-  @Override
-  public String toString(String field) {
-    return ExtendedQueryBase.getOptionsString(this) + "ConstantScore(" + 
filter.toString() + ")";
-  }
-
-  /** Returns true if <code>o</code> is equal to this. */
-  @Override
-  public boolean equals(Object other) {
-    return sameClassAs(other) &&
-           Objects.equals(filter, ((SolrConstantScoreQuery) other).filter);
-  }
-
-  /** Returns a hash code value for this object. */
-  @Override
-  public int hashCode() {
-    return 31 * classHash() + filter.hashCode();
-  }
-
-  @Override
-  public void visit(QueryVisitor visitor) {
-    visitor.visitLeaf(this);
-  }
-
-}
diff --git a/solr/core/src/java/org/apache/solr/search/SolrFilter.java 
b/solr/core/src/java/org/apache/solr/search/SolrFilter.java
deleted file mode 100644
index eb3f0ef..0000000
--- a/solr/core/src/java/org/apache/solr/search/SolrFilter.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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.
- */
-package org.apache.solr.search;
-
-import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.search.IndexSearcher;
-import org.apache.lucene.search.DocIdSet;
-import org.apache.lucene.util.Bits;
-
-import java.util.Map;
-import java.io.IOException;
-
-
-/** A SolrFilter extends the Lucene Filter and adds extra semantics such as 
passing on
- * weight context info for function queries.
- *
- * Experimental and subject to change.
- */
-public abstract class SolrFilter extends Filter {
-
-  /** Implementations should propagate createWeight to sub-ValueSources which 
can store weight info in the context.
-   * The context object will be passed to getDocIdSet() where this info can be 
retrieved. */
-  public abstract void createWeight(Map<Object, Object> context, IndexSearcher 
searcher) throws IOException;
-  
-  public abstract DocIdSet getDocIdSet(Map<Object, Object> context
-          , LeafReaderContext readerContext, Bits acceptDocs) throws 
IOException;
-
-  @Override
-  public DocIdSet getDocIdSet(LeafReaderContext context, Bits acceptDocs) 
throws IOException {
-    return getDocIdSet(null, context, acceptDocs);
-  }
-}
diff --git a/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java 
b/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
index 2e6e336..c909093 100644
--- a/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
+++ b/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
@@ -958,7 +958,7 @@ public class SolrIndexSearcher extends IndexSearcher 
implements Closeable, SolrI
     if (queries == null || queries.size() == 0) {
       if (setFilter != null) {
         pf.answer = setFilter;
-        pf.filter = setFilter.getTopFilter();
+        pf.filter = setFilter.makeQuery();
       }
       return pf;
     }
@@ -1052,7 +1052,7 @@ public class SolrIndexSearcher extends IndexSearcher 
implements Closeable, SolrI
       // "answer" is the only part of the filter, so set it.
       if (answer != null) {
         pf.answer = answer;
-        pf.filter = answer.getTopFilter();
+        pf.filter = answer.makeQuery();
       }
       return pf;
     }
@@ -1061,13 +1061,13 @@ public class SolrIndexSearcher extends IndexSearcher 
implements Closeable, SolrI
     // Set pf.filter based on combining "answer" and "notCached"
     if (notCached == null) {
       if (answer != null) {
-        pf.filter = answer.getTopFilter();
+        pf.filter = answer.makeQuery();
       }
     } else {
       notCached.sort(sortByCost); // pointless?
       final BooleanQuery.Builder builder = new BooleanQuery.Builder();
       if (answer != null) {
-        builder.add(answer.getTopFilter(), Occur.FILTER);
+        builder.add(answer.makeQuery(), Occur.FILTER);
       }
       for (ExtendedQuery eq : notCached) {
         Query q = eq.getCostAppliedQuery();
@@ -2080,7 +2080,7 @@ public class SolrIndexSearcher extends IndexSearcher 
implements Closeable, SolrI
       TotalHitCountCollector collector = new TotalHitCountCollector();
       BooleanQuery.Builder bq = new BooleanQuery.Builder();
       bq.add(QueryUtils.makeQueryable(a), Occur.MUST);
-      bq.add(new ConstantScoreQuery(b.getTopFilter()), Occur.MUST);
+      bq.add(new ConstantScoreQuery(b.makeQuery()), Occur.MUST);
       super.search(bq.build(), collector);
       return collector.getTotalHits();
     }
diff --git a/solr/core/src/java/org/apache/solr/search/SortedIntDocSet.java 
b/solr/core/src/java/org/apache/solr/search/SortedIntDocSet.java
index 94e3d6f..3bdf5d2 100644
--- a/solr/core/src/java/org/apache/solr/search/SortedIntDocSet.java
+++ b/solr/core/src/java/org/apache/solr/search/SortedIntDocSet.java
@@ -25,7 +25,6 @@ import com.carrotsearch.hppc.IntHashSet;
 
 import org.apache.lucene.index.LeafReaderContext;
 import org.apache.lucene.index.ReaderUtil;
-import org.apache.lucene.search.DocIdSet;
 import org.apache.lucene.search.DocIdSetIterator;
 import org.apache.lucene.util.Accountable;
 import org.apache.lucene.util.Bits;
@@ -761,50 +760,8 @@ public class SortedIntDocSet extends DocSet {
   }
 
   @Override
-  public Filter getTopFilter() {
-    return new Filter() {
-
-      @Override
-      public DocIdSet getDocIdSet(final LeafReaderContext context, final Bits 
acceptDocs) {
-        // all Solr DocSets that are used as filters only include live docs
-        final Bits acceptDocs2 = acceptDocs == null ? null : 
(context.reader().getLiveDocs() == acceptDocs ? null : acceptDocs);
-
-        return BitsFilteredDocIdSet.wrap(new DocIdSet() {
-          @Override
-          public DocIdSetIterator iterator() {
-            return SortedIntDocSet.this.iterator(context);
-          }
-
-          @Override
-          public long ramBytesUsed() {
-            return RamUsageEstimator.sizeOf(docs);
-          }
-          
-          @Override
-          public Bits bits() {
-            // random access is expensive for this set
-            return null;
-          }
-
-        }, acceptDocs2);
-      }
-      @Override
-      public String toString(String field) {
-        return "SortedIntDocSetTopFilter";
-      }
-
-      // Equivalence should/could be based on docs here? How did it work 
previously?
-
-      @Override
-      public boolean equals(Object other) {
-        return other == this;
-      }
-
-      @Override
-      public int hashCode() {
-        return System.identityHashCode(this);
-      }
-    };
+  public DocSetQuery makeQuery() {
+    return new DocSetQuery(this);
   }
 
   @Override
diff --git a/solr/core/src/java/org/apache/solr/search/facet/FacetRequest.java 
b/solr/core/src/java/org/apache/solr/search/facet/FacetRequest.java
index b67f536..c78f3e2 100644
--- a/solr/core/src/java/org/apache/solr/search/facet/FacetRequest.java
+++ b/solr/core/src/java/org/apache/solr/search/facet/FacetRequest.java
@@ -32,8 +32,8 @@ import org.apache.solr.request.SolrQueryRequest;
 import org.apache.solr.search.DocSet;
 import org.apache.solr.search.JoinQParserPlugin;
 import org.apache.solr.search.QueryContext;
-import org.apache.solr.search.SolrConstantScoreQuery;
 import org.apache.solr.search.SyntaxError;
+import org.apache.solr.search.WrappedQuery;
 import org.apache.solr.search.join.GraphQuery;
 import org.apache.solr.search.join.GraphQueryParser;
 import org.apache.solr.util.RTimer;
@@ -229,19 +229,19 @@ public abstract class FacetRequest {
        * Creates a Query that can be used to recompute the new "base" for this 
domain, relative to the
        * current base of the FacetContext.
        */
-      public Query createDomainQuery(FacetContext fcontext) throws IOException 
{
+      public Query createDomainQuery(FacetContext fcontext) {
         // NOTE: this code lives here, instead of in 
FacetProcessor.handleJoin, in order to minimize
         // the number of classes that have to know about the number of 
possible settings on the join
         // (ie: if we add a score mode, or some other modifier to how the 
joins are done)
 
-        final SolrConstantScoreQuery fromQuery = new 
SolrConstantScoreQuery(fcontext.base.getTopFilter());
+        final Query fromQuery = fcontext.base.makeQuery();
+        WrappedQuery wrappedFromQuery = new WrappedQuery(fromQuery);
+
         // this shouldn't matter once we're wrapped in a join query, but just 
in case it ever does...
-        fromQuery.setCache(false);
+        wrappedFromQuery.setCache(false);
 
-        return JoinQParserPlugin.createJoinQuery(fromQuery, this.from, 
this.to, this.method);
+        return JoinQParserPlugin.createJoinQuery(wrappedFromQuery, this.from, 
this.to, this.method);
       }
-
-
     }
 
     /** Are we doing a query time graph across other documents */
@@ -287,24 +287,23 @@ public abstract class FacetRequest {
        * Creates a Query that can be used to recompute the new "base" for this 
domain, relative to the
        * current base of the FacetContext.
        */
-      public Query createDomainQuery(FacetContext fcontext) throws IOException 
{
-        final SolrConstantScoreQuery fromQuery = new 
SolrConstantScoreQuery(fcontext.base.getTopFilter());
+      public Query createDomainQuery(FacetContext fcontext) {
+        final Query fromQuery = fcontext.base.makeQuery();
+        WrappedQuery wrappedFromQuery = new WrappedQuery(fromQuery);
+
         // this shouldn't matter once we're wrapped in a join query, but just 
in case it ever does...
-        fromQuery.setCache(false);
+        wrappedFromQuery.setCache(false);
 
         GraphQueryParser graphParser = new GraphQueryParser(null, localParams, 
null, fcontext.req);
         try {
           GraphQuery graphQuery = (GraphQuery)graphParser.parse();
-          graphQuery.setQ(fromQuery);
+          graphQuery.setQ(wrappedFromQuery);
           return graphQuery;
         } catch (SyntaxError syntaxError) {
           throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, 
syntaxError);
         }
       }
-
-
     }
-    
   }
 
   /**
@@ -446,9 +445,5 @@ public abstract class FacetRequest {
   public abstract FacetMerger createFacetMerger(Object prototype);
   
   public abstract Map<String, Object> getFacetDescription();
-
-
 }
 
-
-
diff --git 
a/solr/core/src/java/org/apache/solr/search/function/ValueSourceRangeFilter.java
 
b/solr/core/src/java/org/apache/solr/search/function/ValueSourceRangeFilter.java
index 67cbd23..4a197e7 100644
--- 
a/solr/core/src/java/org/apache/solr/search/function/ValueSourceRangeFilter.java
+++ 
b/solr/core/src/java/org/apache/solr/search/function/ValueSourceRangeFilter.java
@@ -17,16 +17,18 @@
 package org.apache.solr.search.function;
 
 import org.apache.lucene.index.LeafReaderContext;
+import org.apache.lucene.queries.function.FunctionValues;
 import org.apache.lucene.queries.function.ValueSource;
-import org.apache.lucene.search.DocIdSet;
-import org.apache.lucene.search.DocIdSetIterator;
+import org.apache.lucene.queries.function.ValueSourceScorer;
+import org.apache.lucene.search.ConstantScoreScorer;
+import org.apache.lucene.search.ConstantScoreWeight;
+import org.apache.lucene.search.Explanation;
 import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
 import org.apache.lucene.search.ScoreMode;
 import org.apache.lucene.search.Scorer;
 import org.apache.lucene.search.Weight;
-import org.apache.lucene.util.Bits;
-import org.apache.solr.search.BitsFilteredDocIdSet;
-import org.apache.solr.search.SolrFilter;
 
 import java.io.IOException;
 import java.util.Map;
@@ -35,7 +37,7 @@ import java.util.Map;
 /**
  * RangeFilter over a ValueSource.
  */
-public class ValueSourceRangeFilter extends SolrFilter {
+public class ValueSourceRangeFilter extends Query {
   private final ValueSource valueSource;
   private final String lowerVal;
   private final String upperVal;
@@ -76,33 +78,45 @@ public class ValueSourceRangeFilter extends SolrFilter {
     return includeUpper;
   }
 
-
   @Override
-  public DocIdSet getDocIdSet(final Map<Object, Object> context, final 
LeafReaderContext readerContext, Bits acceptDocs) throws IOException {
-    // NB the IndexSearcher parameter here can be null because Filter Weights 
don't
-    // actually use it.
-    Weight weight = createWeight(null, ScoreMode.COMPLETE, 1);
-    return BitsFilteredDocIdSet.wrap(new DocIdSet() {
-       @Override
-       public DocIdSetIterator iterator() throws IOException {
-         Scorer scorer = valueSource.getValues(context, 
readerContext).getRangeScorer(weight, readerContext, lowerVal, upperVal, 
includeLower, includeUpper);
-         return scorer == null ? null : scorer.iterator();
-       }
-       @Override
-       public Bits bits() {
-         return null;  // don't use random access
-       }
-
-       @Override
-       public long ramBytesUsed() {
-         return 0L;
-       }
-     }, acceptDocs);
+  public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, 
float boost) throws IOException {
+    return new FunctionRangeWeight(searcher, scoreMode, boost);
   }
 
-  @Override
-  public void createWeight(Map<Object, Object> context, IndexSearcher 
searcher) throws IOException {
-    valueSource.createWeight(context, searcher);
+  private class FunctionRangeWeight extends ConstantScoreWeight {
+    private final Map<Object, Object> vsContext;
+    private final ScoreMode scoreMode;
+
+    public FunctionRangeWeight(IndexSearcher searcher, ScoreMode scoreMode, 
float boost) throws IOException {
+      super(ValueSourceRangeFilter.this, boost);
+      this.scoreMode = scoreMode;
+      vsContext = ValueSource.newContext(searcher);
+      valueSource.createWeight(vsContext, searcher); // callback on 
valueSource tree
+    }
+
+    @Override
+    public Explanation explain(LeafReaderContext context, int doc) throws 
IOException {
+      FunctionValues functionValues = valueSource.getValues(vsContext, 
context);
+      ValueSourceScorer scorer = functionValues.getRangeScorer(this, context, 
lowerVal, upperVal, includeLower, includeUpper);
+      if (scorer.matches(doc)) {
+        scorer.iterator().advance(doc);
+        return Explanation.match(scorer.score(), 
ValueSourceRangeFilter.this.toString(), functionValues.explain(doc));
+      } else {
+        return Explanation.noMatch(ValueSourceRangeFilter.this.toString(), 
functionValues.explain(doc));
+      }
+    }
+
+    @Override
+    public Scorer scorer(LeafReaderContext context) throws IOException {
+      ValueSourceScorer scorer = valueSource.getValues(vsContext, context)
+              .getRangeScorer(this, context, lowerVal, upperVal, includeLower, 
includeUpper);
+      return new ConstantScoreScorer(this, score(), scoreMode, 
scorer.iterator());
+    }
+
+    @Override
+    public boolean isCacheable(LeafReaderContext ctx) {
+      return false;
+    }
   }
 
   @Override
@@ -120,6 +134,12 @@ public class ValueSourceRangeFilter extends SolrFilter {
   }
 
   @Override
+  public void visit(QueryVisitor visitor) {
+    visitor.visitLeaf(this);
+  }
+
+
+  @Override
   public boolean equals(Object o) {
     if (this == o) return true;
     if (!(o instanceof ValueSourceRangeFilter)) return false;
diff --git a/solr/core/src/test/org/apache/solr/search/TestDocSet.java 
b/solr/core/src/test/org/apache/solr/search/TestDocSet.java
index 47f481a..02492fc 100644
--- a/solr/core/src/test/org/apache/solr/search/TestDocSet.java
+++ b/solr/core/src/test/org/apache/solr/search/TestDocSet.java
@@ -22,7 +22,6 @@ import java.util.List;
 import java.util.Random;
 import java.util.function.Supplier;
 import java.util.function.ToIntFunction;
-
 import org.apache.lucene.index.BinaryDocValues;
 import org.apache.lucene.index.FieldInfos;
 import org.apache.lucene.index.Fields;
@@ -42,6 +41,8 @@ import org.apache.lucene.index.Terms;
 import org.apache.lucene.index.VectorValues;
 import org.apache.lucene.search.DocIdSet;
 import org.apache.lucene.search.DocIdSetIterator;
+import org.apache.lucene.search.ScoreMode;
+import org.apache.lucene.search.Scorer;
 import org.apache.lucene.search.TopDocs;
 import org.apache.lucene.search.TotalHits;
 import org.apache.lucene.util.BitSetIterator;
@@ -55,6 +56,7 @@ import org.apache.solr.SolrTestCase;
  */
 public class TestDocSet extends SolrTestCase {
   Random rand;
+  private Object IndexSearcher;
 
   @Override
   public void setUp() throws Exception {
@@ -533,12 +535,12 @@ public class TestDocSet extends SolrTestCase {
     }
   }
 
+
   /**
    * Tests equivalence among {@link DocIdSetIterator} instances retrieved from 
{@link BitDocSet} and {@link SortedIntDocSet}
-   * implementations, via {@link DocSet#getTopFilter()}/{@link 
Filter#getDocIdSet(LeafReaderContext, Bits)} and directly
-   * via {@link DocSet#iterator(LeafReaderContext)}.
-   * Also tests corresponding random-access {@link Bits} instances retrieved 
via {@link DocSet#getTopFilter()}/
-   * {@link Filter#getDocIdSet(LeafReaderContext, Bits)}/{@link 
DocIdSet#bits()}.
+   * implementations, via {@link DocSet#makeQuery()} and directly via {@link 
DocSet#iterator(LeafReaderContext)}.
+   * Also tests corresponding random-access {@link Bits} instances retrieved 
via {@link DocSet#makeQuery()}/
+   * {@link DocIdSet#bits()}.
    */
   public void doFilterTest(IndexReader reader) throws IOException {
     IndexReaderContext topLevelContext = reader.getContext();
@@ -546,8 +548,8 @@ public class TestDocSet extends SolrTestCase {
     DocSet a = new BitDocSet(bs);
     DocSet b = getIntDocSet(bs);
 
-    Filter fa = a.getTopFilter();
-    Filter fb = b.getTopFilter();
+//    Query fa = a.makeQuery();
+//    Query fb = b.makeQuery();
 
     /* top level filters are no longer supported
     // test top-level
@@ -556,30 +558,18 @@ public class TestDocSet extends SolrTestCase {
     doTestIteratorEqual(da, db);
     ***/
 
-    DocIdSet da;
-    DocIdSet db;
     List<LeafReaderContext> leaves = topLevelContext.leaves();
-
     // first test in-sequence sub readers
     for (LeafReaderContext readerContext : leaves) {
-      da = fa.getDocIdSet(readerContext, null);
-      db = fb.getDocIdSet(readerContext, null);
-
       // there are various ways that disis can be retrieved for each 
leafReader; they should all be equivalent.
-      doTestIteratorEqual(da.bits(), disiSupplier(da), disiSupplier(db), () -> 
a.iterator(readerContext), () -> b.iterator(readerContext));
-
-      // set b is SortedIntDocSet, so derivatives should not support 
random-access via Bits
-      assertNull(db.bits());
+         doTestIteratorEqual(getExpectedBits(a, readerContext), () -> 
a.iterator(readerContext), () -> b.iterator(readerContext));
     }  
 
     int nReaders = leaves.size();
     // now test out-of-sequence sub readers
     for (int i=0; i<nReaders; i++) {
       LeafReaderContext readerContext = leaves.get(rand.nextInt(nReaders));
-      da = fa.getDocIdSet(readerContext, null);
-      db = fb.getDocIdSet(readerContext, null);
-      doTestIteratorEqual(da.bits(), disiSupplier(da), disiSupplier(db), () -> 
a.iterator(readerContext), () -> b.iterator(readerContext));
-      assertNull(db.bits());
+      doTestIteratorEqual(getExpectedBits(a, readerContext), () -> 
a.iterator(readerContext), () -> b.iterator(readerContext));
     }
   }
 
@@ -587,10 +577,35 @@ public class TestDocSet extends SolrTestCase {
     // keeping these numbers smaller help hit more edge cases
     int maxSeg=4;
     int maxDoc=5;    // increase if future changes add more edge cases (like 
probing a certain distance in the bin search)
-
     for (int i=0; i<5000; i++) {
       IndexReader r = dummyMultiReader(maxSeg, maxDoc);
       doFilterTest(r);
     }
   }
+
+  private DocIdSetIterator getDocIdSetIteratorFromQuery(DocSetQuery dsq, 
LeafReaderContext readerContext) throws IOException {
+    Scorer scorer = dsq.createWeight(null, ScoreMode.COMPLETE_NO_SCORES, 
0).scorer(readerContext);
+    return scorer != null ? scorer.iterator() : null;
+  }
+
+  private Bits getExpectedBits(final DocSet docSet, final LeafReaderContext 
context) {
+    if (context.isTopLevel) {
+      return docSet.getBits();
+    }
+
+    final int base = context.docBase;
+    final int length = context.reader().maxDoc();
+    final FixedBitSet bs = docSet.getFixedBitSet();
+    return new Bits() {
+      @Override
+      public boolean get(int index) {
+        return bs.get(index + base);
+      }
+
+      @Override
+      public int length() {
+        return length;
+      }
+    };
+  }
 }
diff --git 
a/solr/core/src/test/org/apache/solr/search/TestFilteredDocIdSet.java 
b/solr/core/src/test/org/apache/solr/search/TestFilteredDocIdSet.java
index cc9ec0a..ceac7ee 100644
--- a/solr/core/src/test/org/apache/solr/search/TestFilteredDocIdSet.java
+++ b/solr/core/src/test/org/apache/solr/search/TestFilteredDocIdSet.java
@@ -32,11 +32,15 @@ import org.apache.lucene.search.BooleanClause.Occur;
 import org.apache.lucene.search.BooleanQuery;
 import org.apache.lucene.search.DocIdSet;
 import org.apache.lucene.search.DocIdSetIterator;
+import org.apache.lucene.search.Explanation;
 import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.MatchAllDocsQuery;
 import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
+import org.apache.lucene.search.ScoreMode;
+import org.apache.lucene.search.Scorer;
+import org.apache.lucene.search.Weight;
 import org.apache.lucene.store.Directory;
-import org.apache.lucene.util.Bits;
 import org.apache.solr.SolrTestCase;
 
 public class TestFilteredDocIdSet extends SolrTestCase {
@@ -79,7 +83,6 @@ public class TestFilteredDocIdSet extends SolrTestCase {
         } 
       };
 
-
     DocIdSet filteredSet = new FilteredDocIdSet(innerSet){
         @Override
         protected boolean match(int docid) {
@@ -113,7 +116,7 @@ public class TestFilteredDocIdSet extends SolrTestCase {
   }
   
   public void testNullDocIdSet() throws Exception {
-    // Tests that if a Filter produces a null DocIdSet, which is given to
+    // (historical note) Tests that if a Query produces a null DocIdSet, which 
is given to
     // IndexSearcher, everything works fine. This came up in LUCENE-1754.
     Directory dir = newDirectory();
     RandomIndexWriter writer = new RandomIndexWriter(random(), dir);
@@ -127,22 +130,42 @@ public class TestFilteredDocIdSet extends SolrTestCase {
     IndexSearcher searcher = newSearcher(reader);
     Assert.assertEquals(1, searcher.search(new MatchAllDocsQuery(), 
10).totalHits.value);
     
-    // Now search w/ a Filter which returns a null DocIdSet
-    Filter f = new Filter() {
+    // Now search w/ a Query which returns a null Scorer
+    DocSetQuery f = new DocSetQuery(null) {
       @Override
-      public DocIdSet getDocIdSet(LeafReaderContext context, Bits acceptDocs) {
-        return null;
+      public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, 
float boost) {
+        return new Weight(this) {
+
+          @Override
+          public Explanation explain(LeafReaderContext context, int doc) {
+              return Explanation.match(0f, "No match on id " + doc);
+          }
+
+          @Override
+          public Scorer scorer(LeafReaderContext leafReaderContext) {
+            return null;
+          }
+
+          @Override
+          public boolean isCacheable(LeafReaderContext ctx) {
+            return false;
+          }
+        };
       }
+
       @Override
-      public String toString(String field) {
+      public String toString(String s) {
         return "nullDocIdSetFilter";
       }
-      
+
       @Override
-      public boolean equals(Object other) {
-        return other == this;
+      public void visit(QueryVisitor queryVisitor) {}
+
+      @Override
+      public boolean equals(Object o) {
+        return o == this;
       }
-      
+
       @Override
       public int hashCode() {
         return System.identityHashCode(this);
@@ -171,25 +194,25 @@ public class TestFilteredDocIdSet extends SolrTestCase {
     IndexSearcher searcher = newSearcher(reader);
     Assert.assertEquals(1, searcher.search(new MatchAllDocsQuery(), 
10).totalHits.value);
     
-      // Now search w/ a Filter which returns a null DocIdSet
-    Filter f = new Filter() {
+    // Now search w/ a Query which returns a null Scorer
+    Query f = new Query() {
       @Override
-      public DocIdSet getDocIdSet(LeafReaderContext context, Bits acceptDocs) {
-        final DocIdSet innerNullIteratorSet = new DocIdSet() {
+      public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, 
float boost) {
+        return new Weight(this) {
+
           @Override
-          public DocIdSetIterator iterator() {
-            return null;
-          } 
+          public Explanation explain(LeafReaderContext context, int doc) {
+              return Explanation.match(0f, "No match on id " + doc);
+          }
 
           @Override
-          public long ramBytesUsed() {
-            return 0L;
+          public Scorer scorer(LeafReaderContext leafReaderContext) {
+            return null;
           }
-        };
-        return new FilteredDocIdSet(innerNullIteratorSet) {
+
           @Override
-          protected boolean match(int docid) {
-            return true;
+          public boolean isCacheable(LeafReaderContext ctx) {
+            return false;
           }
         };
       }
@@ -198,7 +221,10 @@ public class TestFilteredDocIdSet extends SolrTestCase {
       public String toString(String field) {
         return "nullDocIdSetFilter";
       }
-      
+
+      @Override
+      public void visit(QueryVisitor queryVisitor) {}
+
       @Override
       public boolean equals(Object other) {
         return other == this;
@@ -218,5 +244,4 @@ public class TestFilteredDocIdSet extends SolrTestCase {
     reader.close();
     dir.close();
   }
-
 }
diff --git a/solr/core/src/test/org/apache/solr/search/TestSort.java 
b/solr/core/src/test/org/apache/solr/search/TestSort.java
index c95e9b6..365eba9 100644
--- a/solr/core/src/test/org/apache/solr/search/TestSort.java
+++ b/solr/core/src/test/org/apache/solr/search/TestSort.java
@@ -35,20 +35,25 @@ import org.apache.lucene.index.IndexWriterConfig;
 import org.apache.lucene.index.LeafReaderContext;
 import org.apache.lucene.search.Collector;
 import org.apache.lucene.search.DocIdSet;
+import org.apache.lucene.search.Explanation;
 import org.apache.lucene.search.FilterCollector;
 import org.apache.lucene.search.FilterLeafCollector;
 import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.LeafCollector;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
 import org.apache.lucene.search.ScoreDoc;
+import org.apache.lucene.search.ScoreMode;
+import org.apache.lucene.search.Scorer;
 import org.apache.lucene.search.Sort;
 import org.apache.lucene.search.SortField.Type;
 import org.apache.lucene.search.SortField;
 import org.apache.lucene.search.TopDocs;
 import org.apache.lucene.search.TopFieldCollector;
+import org.apache.lucene.search.Weight;
 import org.apache.lucene.store.ByteBuffersDirectory;
 import org.apache.lucene.store.Directory;
 import org.apache.lucene.util.BitDocIdSet;
-import org.apache.lucene.util.Bits;
 import org.apache.lucene.util.FixedBitSet;
 import org.apache.lucene.util.TestUtil;
 import org.apache.solr.SolrTestCaseJ4;
@@ -182,7 +187,6 @@ public class TestSort extends SolrTestCaseJ4 {
   }
 
 
-
   public void testSort() throws Exception {
     Directory dir = new ByteBuffersDirectory();
     Field f = new StringField("f", "0", Field.Store.NO);
@@ -236,17 +240,37 @@ public class TestSort extends SolrTestCaseJ4 {
       assertTrue(reader.leaves().size() > 1);
 
       for (int i=0; i<qiter; i++) {
-        Filter filt = new Filter() {
+        Query query = new Query() {
           @Override
-          public DocIdSet getDocIdSet(LeafReaderContext context, Bits 
acceptDocs) {
-            return 
BitsFilteredDocIdSet.wrap(randSet(context.reader().maxDoc()), acceptDocs);
+          public Weight createWeight(IndexSearcher searcher, ScoreMode 
scoreMode, float boost) {
+            return new Weight(this) {
+
+              @Override
+              public Explanation explain(LeafReaderContext context, int doc) {
+                  return Explanation.match(0f, "No match on id " + doc);
+              }
+
+              @Override
+              public Scorer scorer(LeafReaderContext leafReaderContext) {
+                return null;
+              }
+
+              @Override
+              public boolean isCacheable(LeafReaderContext ctx) {
+                return false;
+              }
+            };
           }
+
           @Override
           public String toString(String field) {
             return "TestSortFilter";
           }
 
           @Override
+          public void visit(QueryVisitor queryVisitor) { 
queryVisitor.visitLeaf(this); }
+
+          @Override
           public boolean equals(Object other) {
             return other == this;
           }
@@ -302,10 +326,9 @@ public class TestSort extends SolrTestCaseJ4 {
               }
             };
           }
-
         };
 
-        searcher.search(filt, myCollector);
+        searcher.search(query, myCollector);
 
         Collections.sort(collectedDocs, (o1, o2) -> {
           String v1 = o1.val == null ? nullRep : o1.val;
@@ -341,7 +364,6 @@ public class TestSort extends SolrTestCaseJ4 {
       reader.close();
     }
     dir.close();
-
   }
 
   public DocIdSet randSet(int sz) {
diff --git 
a/solr/modules/analytics/src/java/org/apache/solr/analytics/AnalyticsDriver.java
 
b/solr/modules/analytics/src/java/org/apache/solr/analytics/AnalyticsDriver.java
index 21b7d13..dff2131 100644
--- 
a/solr/modules/analytics/src/java/org/apache/solr/analytics/AnalyticsDriver.java
+++ 
b/solr/modules/analytics/src/java/org/apache/solr/analytics/AnalyticsDriver.java
@@ -18,16 +18,15 @@ package org.apache.solr.analytics;
 
 import java.io.IOException;
 import java.util.List;
-
 import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.search.DocIdSet;
 import org.apache.lucene.search.DocIdSetIterator;
+import org.apache.lucene.search.Query;
 import org.apache.solr.analytics.AnalyticsRequestManager.StreamingInfo;
 import 
org.apache.solr.analytics.facet.AbstractSolrQueryFacet.FacetValueQueryExecuter;
 import org.apache.solr.analytics.facet.StreamingFacet;
 import org.apache.solr.analytics.function.ReductionCollectionManager;
 import org.apache.solr.request.SolrQueryRequest;
-import org.apache.solr.search.Filter;
+import org.apache.solr.search.DocSet;
 import org.apache.solr.search.SolrIndexSearcher;
 
 public class AnalyticsDriver {
@@ -41,12 +40,13 @@ public class AnalyticsDriver {
    * @param queryRequest used for the search request
    * @throws IOException if an error occurs while reading from Solr
    */
-  public static void drive(AnalyticsRequestManager manager, SolrIndexSearcher 
searcher, Filter filter, SolrQueryRequest queryRequest) throws IOException {
+  public static void drive(AnalyticsRequestManager manager, SolrIndexSearcher 
searcher, DocSet filter, SolrQueryRequest queryRequest) throws IOException {
     StreamingInfo streamingInfo = manager.getStreamingFacetInfo();
     Iterable<StreamingFacet> streamingFacets = streamingInfo.streamingFacets;
     ReductionCollectionManager collectionManager = 
streamingInfo.streamingCollectionManager;
 
-    Iterable<FacetValueQueryExecuter> facetExecuters = 
manager.getFacetExecuters(filter, queryRequest);
+    Query fq = filter.makeQuery(); //TODO: passing this along as a DocSet 
would affect a lot of APIs
+    Iterable<FacetValueQueryExecuter> facetExecuters = 
manager.getFacetExecuters(fq, queryRequest);
 
     // Streaming phase (Overall results & Value/Pivot Facets)
     // Loop through all documents and collect reduction data for streaming 
facets and overall results
@@ -54,11 +54,7 @@ public class AnalyticsDriver {
       List<LeafReaderContext> contexts = 
searcher.getTopReaderContext().leaves();
       for (int leafNum = 0; leafNum < contexts.size(); leafNum++) {
         LeafReaderContext context = contexts.get(leafNum);
-        DocIdSet dis = filter.getDocIdSet(context, null); // solr docsets 
already exclude any deleted docs
-        if (dis == null) {
-          continue;
-        }
-        DocIdSetIterator disi = dis.iterator();
+        DocIdSetIterator disi = filter.iterator(context);
         if (disi != null) {
           collectionManager.doSetNextReader(context);
           int doc = disi.nextDoc();
diff --git 
a/solr/modules/analytics/src/java/org/apache/solr/analytics/AnalyticsGroupingManager.java
 
b/solr/modules/analytics/src/java/org/apache/solr/analytics/AnalyticsGroupingManager.java
index 75b3ad9..cf9e54a5 100644
--- 
a/solr/modules/analytics/src/java/org/apache/solr/analytics/AnalyticsGroupingManager.java
+++ 
b/solr/modules/analytics/src/java/org/apache/solr/analytics/AnalyticsGroupingManager.java
@@ -25,6 +25,7 @@ import java.util.Map;
 import java.util.Map.Entry;
 import java.util.function.Consumer;
 
+import org.apache.lucene.search.Query;
 import org.apache.solr.analytics.facet.AnalyticsFacet;
 import org.apache.solr.analytics.facet.PivotFacet;
 import org.apache.solr.analytics.facet.AbstractSolrQueryFacet;
@@ -38,7 +39,6 @@ import 
org.apache.solr.analytics.function.ReductionCollectionManager;
 import org.apache.solr.analytics.util.AnalyticsResponseHeadings;
 import org.apache.solr.common.util.NamedList;
 import org.apache.solr.request.SolrQueryRequest;
-import org.apache.solr.search.Filter;
 
 /**
  * The manager for faceted analytics. This class manages one grouping of 
facets and expressions to compute
@@ -98,13 +98,12 @@ public class AnalyticsGroupingManager {
    * One {@link FacetValueQueryExecuter} is created for each facet value to be 
returned for a facet.
    * Since every {@link AbstractSolrQueryFacet} has discrete and user-defined 
facet values,
    * unlike {@link StreamingFacet}s, a discrete number of {@link 
FacetValueQueryExecuter}s are created and returned.
-   *
    * @param filter representing the overall Solr Query of the request,
    * will be combined with the facet value queries
    * @param queryRequest from the overall search request
    * @param cons where the executers are passed to
    */
-  public void getFacetExecuters(Filter filter, SolrQueryRequest queryRequest, 
Consumer<FacetValueQueryExecuter> cons) {
+  public void getFacetExecuters(Query filter, SolrQueryRequest queryRequest, 
Consumer<FacetValueQueryExecuter> cons) {
     facets.forEach( (name, facet) -> {
       if (facet instanceof AbstractSolrQueryFacet) {
         ((AbstractSolrQueryFacet)facet).createFacetValueExecuters(filter, 
queryRequest, cons);
diff --git 
a/solr/modules/analytics/src/java/org/apache/solr/analytics/AnalyticsRequestManager.java
 
b/solr/modules/analytics/src/java/org/apache/solr/analytics/AnalyticsRequestManager.java
index 68ae155..7d7bf38 100644
--- 
a/solr/modules/analytics/src/java/org/apache/solr/analytics/AnalyticsRequestManager.java
+++ 
b/solr/modules/analytics/src/java/org/apache/solr/analytics/AnalyticsRequestManager.java
@@ -24,6 +24,7 @@ import java.util.Collection;
 import java.util.HashMap;
 import java.util.Map;
 
+import org.apache.lucene.search.Query;
 import org.apache.solr.analytics.facet.AbstractSolrQueryFacet;
 import 
org.apache.solr.analytics.facet.AbstractSolrQueryFacet.FacetValueQueryExecuter;
 import org.apache.solr.analytics.facet.StreamingFacet;
@@ -34,7 +35,6 @@ import 
org.apache.solr.analytics.stream.AnalyticsShardRequestManager;
 import org.apache.solr.analytics.util.AnalyticsResponseHeadings;
 import org.apache.solr.common.util.NamedList;
 import org.apache.solr.request.SolrQueryRequest;
-import org.apache.solr.search.Filter;
 
 /**
  * The manager of an entire analytics request.
@@ -228,7 +228,7 @@ public class AnalyticsRequestManager {
    * @param queryRequest of the overall search query
    * @return an {@link Iterable} of executers
    */
-  public Iterable<FacetValueQueryExecuter> getFacetExecuters(Filter filter, 
SolrQueryRequest queryRequest) {
+  public Iterable<FacetValueQueryExecuter> getFacetExecuters(Query filter, 
SolrQueryRequest queryRequest) {
     ArrayList<FacetValueQueryExecuter> facetExecutors = new ArrayList<>();
     groupingManagers.values().forEach( grouping -> {
       grouping.getFacetExecuters(filter, queryRequest, executor -> 
facetExecutors.add(executor));
diff --git 
a/solr/modules/analytics/src/java/org/apache/solr/analytics/facet/AbstractSolrQueryFacet.java
 
b/solr/modules/analytics/src/java/org/apache/solr/analytics/facet/AbstractSolrQueryFacet.java
index 56f917a..3f24971 100644
--- 
a/solr/modules/analytics/src/java/org/apache/solr/analytics/facet/AbstractSolrQueryFacet.java
+++ 
b/solr/modules/analytics/src/java/org/apache/solr/analytics/facet/AbstractSolrQueryFacet.java
@@ -26,7 +26,6 @@ import org.apache.lucene.search.SimpleCollector;
 import org.apache.solr.analytics.AnalyticsDriver;
 import 
org.apache.solr.analytics.function.ReductionCollectionManager.ReductionDataCollection;
 import org.apache.solr.request.SolrQueryRequest;
-import org.apache.solr.search.Filter;
 import org.apache.solr.search.SolrIndexSearcher;
 
 /**
@@ -50,11 +49,11 @@ public abstract class AbstractSolrQueryFacet extends 
AnalyticsFacet {
    *
    * Each of these executors will be executed after the streaming phase in the 
{@link AnalyticsDriver}.
    *
-   * @param filter the overall filter representing the documents being used 
for the analytics request
+   * @param filter the overall query representing the documents being used for 
the analytics request
    * @param queryRequest the queryRequest
    * @param consumer the consumer of each facet value's executer
    */
-  public abstract void createFacetValueExecuters(final Filter filter, 
SolrQueryRequest queryRequest, Consumer<FacetValueQueryExecuter> consumer);
+  public abstract void createFacetValueExecuters(final Query filter, 
SolrQueryRequest queryRequest, Consumer<FacetValueQueryExecuter> consumer);
 
   /**
    * This executer is in charge of issuing the Solr query for a facet value 
and collecting results as the query is processed.
diff --git 
a/solr/modules/analytics/src/java/org/apache/solr/analytics/facet/QueryFacet.java
 
b/solr/modules/analytics/src/java/org/apache/solr/analytics/facet/QueryFacet.java
index 2e82f62..f48338b 100644
--- 
a/solr/modules/analytics/src/java/org/apache/solr/analytics/facet/QueryFacet.java
+++ 
b/solr/modules/analytics/src/java/org/apache/solr/analytics/facet/QueryFacet.java
@@ -24,7 +24,6 @@ import 
org.apache.solr.analytics.function.ReductionCollectionManager.ReductionDa
 import org.apache.solr.common.SolrException;
 import org.apache.solr.common.SolrException.ErrorCode;
 import org.apache.solr.request.SolrQueryRequest;
-import org.apache.solr.search.Filter;
 import org.apache.solr.search.QParser;
 import org.apache.solr.search.QueryUtils;
 
@@ -40,7 +39,7 @@ public class QueryFacet extends AbstractSolrQueryFacet {
   }
 
   @Override
-  public void createFacetValueExecuters(final Filter filter, SolrQueryRequest 
queryRequest, Consumer<FacetValueQueryExecuter> consumer) {
+  public void createFacetValueExecuters(final Query filter, SolrQueryRequest 
queryRequest, Consumer<FacetValueQueryExecuter> consumer) {
     queries.forEach( (queryName, query) -> {
       final Query q;
       try {
diff --git 
a/solr/modules/analytics/src/java/org/apache/solr/analytics/facet/RangeFacet.java
 
b/solr/modules/analytics/src/java/org/apache/solr/analytics/facet/RangeFacet.java
index ac9bf16..bb6a41c 100644
--- 
a/solr/modules/analytics/src/java/org/apache/solr/analytics/facet/RangeFacet.java
+++ 
b/solr/modules/analytics/src/java/org/apache/solr/analytics/facet/RangeFacet.java
@@ -28,7 +28,6 @@ import 
org.apache.solr.common.params.FacetParams.FacetRangeInclude;
 import org.apache.solr.common.params.FacetParams.FacetRangeOther;
 import org.apache.solr.request.SolrQueryRequest;
 import org.apache.solr.schema.SchemaField;
-import org.apache.solr.search.Filter;
 import org.apache.solr.search.QueryUtils;
 
 /**
@@ -54,7 +53,7 @@ public class RangeFacet extends AbstractSolrQueryFacet {
   }
 
   @Override
-  public void createFacetValueExecuters(final Filter filter, SolrQueryRequest 
queryRequest, Consumer<FacetValueQueryExecuter> consumer) {
+  public void createFacetValueExecuters(final Query filter, SolrQueryRequest 
queryRequest, Consumer<FacetValueQueryExecuter> consumer) {
     // Computes the end points of the ranges in the rangeFacet
     final FacetRangeGenerator<? extends Comparable<?>> rec = 
FacetRangeGenerator.create(this);
     final SchemaField sf = field;
diff --git 
a/solr/modules/analytics/src/java/org/apache/solr/handler/AnalyticsHandler.java 
b/solr/modules/analytics/src/java/org/apache/solr/handler/AnalyticsHandler.java
index ede5041..ada58c5 100644
--- 
a/solr/modules/analytics/src/java/org/apache/solr/handler/AnalyticsHandler.java
+++ 
b/solr/modules/analytics/src/java/org/apache/solr/handler/AnalyticsHandler.java
@@ -39,7 +39,6 @@ import 
org.apache.solr.response.AnalyticsShardResponseWriter.AnalyticsResponse;
 import org.apache.solr.response.SolrQueryResponse;
 import org.apache.solr.schema.IndexSchema;
 import org.apache.solr.search.DocSet;
-import org.apache.solr.search.Filter;
 import org.apache.solr.search.QParser;
 import org.apache.solr.search.QParserPlugin;
 import org.apache.solr.search.QueryParsing;
@@ -88,8 +87,7 @@ public class AnalyticsHandler extends RequestHandlerBase 
implements SolrCoreAwar
                                                                 false);
       // Collect the reduction data for the request
       SolrIndexSearcher searcher = req.getSearcher();
-      Filter filter = docs.getTopFilter();
-      AnalyticsDriver.drive(manager, searcher, filter, req);
+      AnalyticsDriver.drive(manager, searcher, docs, req);
 
       // Do not calculate results, instead export the reduction data for this 
shard.
       rsp.addResponse(new AnalyticsResponse(manager));
diff --git 
a/solr/modules/analytics/src/java/org/apache/solr/handler/component/AnalyticsComponent.java
 
b/solr/modules/analytics/src/java/org/apache/solr/handler/component/AnalyticsComponent.java
index a743586..1725664 100644
--- 
a/solr/modules/analytics/src/java/org/apache/solr/handler/component/AnalyticsComponent.java
+++ 
b/solr/modules/analytics/src/java/org/apache/solr/handler/component/AnalyticsComponent.java
@@ -85,7 +85,7 @@ public class AnalyticsComponent extends SearchComponent {
     }
     AnalyticsRequestManager reqManager = getAnalyticsRequestManager(rb);
     // Collect the data and generate a response
-    AnalyticsDriver.drive(reqManager, rb.req.getSearcher(), 
rb.getResults().docSet.getTopFilter(), rb.req);
+    AnalyticsDriver.drive(reqManager, rb.req.getSearcher(), 
rb.getResults().docSet, rb.req);
 
     if (rb.isOlapAnalytics()) {
       rb.rsp.add(AnalyticsResponseHeadings.COMPLETED_OLD_HEADER, 
reqManager.createOldResponse());
diff --git 
a/solr/modules/ltr/src/java/org/apache/solr/ltr/feature/SolrFeature.java 
b/solr/modules/ltr/src/java/org/apache/solr/ltr/feature/SolrFeature.java
index 2c1141e..83b8b11 100644
--- a/solr/modules/ltr/src/java/org/apache/solr/ltr/feature/SolrFeature.java
+++ b/solr/modules/ltr/src/java/org/apache/solr/ltr/feature/SolrFeature.java
@@ -175,7 +175,7 @@ public class SolrFeature extends Feature {
 
           DocSet filtersDocSet = searcher.getDocSet(filterQueries); // execute
           if (filtersDocSet != searcher.getLiveDocSet()) {
-            filterDocSetQuery = filtersDocSet.getTopFilter();
+            filterDocSetQuery = filtersDocSet.makeQuery();
           }
         }
 
diff --git 
a/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-9.adoc 
b/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-9.adoc
index a64be85..a7abc81 100644
--- 
a/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-9.adoc
+++ 
b/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-9.adoc
@@ -311,5 +311,7 @@ Example has been provided in `sample_techproducts_configs` 
to override content-t
 * SOLR-15124: Removed three core level admin API endpoints because they are 
already registered at the node level
 where they really belong: /admin/threads, /admin/properties, /admin/logging
 
+* SOLR-12336: Remove Filter, SolrFilter and SolrConstantScoreQuery
+
 * SOLR-15949: Docker: the official image now uses Java 17 provided by Eclipse 
Temurin.  Formerly it was Java 11 from OpenJDK.
-(janhoy, David Smiley)
\ No newline at end of file
+(janhoy, David Smiley)

Reply via email to