1 package org.apache.lucene.search;
4 * Licensed to the Apache Software Foundation (ASF) under one or more
5 * contributor license agreements. See the NOTICE file distributed with
6 * this work for additional information regarding copyright ownership.
7 * The ASF licenses this file to You under the Apache License, Version 2.0
8 * (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
20 import java.io.IOException;
22 import org.apache.lucene.search.BooleanClause.Occur;
25 * Expert: Common scoring functionality for different types of queries.
28 * A <code>Scorer</code> iterates over documents matching a
29 * query in increasing order of doc Id.
32 * Document scores are computed using a given <code>Similarity</code>
36 * <p><b>NOTE</b>: The values Float.Nan,
37 * Float.NEGATIVE_INFINITY and Float.POSITIVE_INFINITY are
38 * not valid scores. Certain collectors (eg {@link
39 * TopScoreDocCollector}) will not properly collect hits
42 public abstract class Scorer extends DocIdSetIterator {
43 private final Similarity similarity;
44 protected final Weight weight;
48 * @param weight The scorers <code>Weight</code>.
50 protected Scorer(Weight weight) {
54 /** Constructs a Scorer.
55 * @param similarity The <code>Similarity</code> implementation used by this scorer.
56 * @deprecated Use {@link #Scorer(Weight)} instead.
59 protected Scorer(Similarity similarity) {
60 this(similarity, null);
65 * @param similarity The <code>Similarity</code> implementation used by this scorer.
66 * @param weight The scorers <code>Weight</code>
67 * @deprecated Use {@link #Scorer(Weight)} instead.
70 protected Scorer(Similarity similarity, Weight weight) {
71 this.similarity = similarity;
75 /** Returns the Similarity implementation used by this scorer.
76 * @deprecated Store any Similarity you might need privately in your implementation instead.
79 public Similarity getSimilarity() {
80 return this.similarity;
83 /** Scores and collects all matching documents.
84 * @param collector The collector to which all matching documents are passed.
86 public void score(Collector collector) throws IOException {
87 collector.setScorer(this);
89 while ((doc = nextDoc()) != NO_MORE_DOCS) {
90 collector.collect(doc);
95 * Expert: Collects matching documents in a range. Hook for optimization.
96 * Note, <code>firstDocID</code> is added to ensure that {@link #nextDoc()}
97 * was called before this method.
99 * <p><b>NOTE:</b> Because of backwards compatibility, this method is still
100 * declared as <b>protected</b>, but it is intended to be <b>public</b>,
101 * because it's called from other classes (like BooleanScorer).
102 * If you subclass {@code Scorer}, you should declare the overridden method
103 * as public to ease transition to Lucene 4.0, where it will be public.</p>
106 * The collector to which all matching documents are passed.
108 * Do not score documents past this.
110 * The first document ID (ensures {@link #nextDoc()} is called before
112 * @return true if more matching documents may remain.
114 protected boolean score(Collector collector, int max, int firstDocID) throws IOException {
115 collector.setScorer(this);
116 int doc = firstDocID;
118 collector.collect(doc);
121 return doc != NO_MORE_DOCS;
124 /** Returns the score of the current document matching the query.
125 * Initially invalid, until {@link #nextDoc()} or {@link #advance(int)}
126 * is called the first time, or when called from within
127 * {@link Collector#collect}.
129 public abstract float score() throws IOException;
131 /** Returns number of matches for the current document.
132 * This returns a float (not int) because
133 * SloppyPhraseScorer discounts its freq according to how
134 * "sloppy" the match was.
136 * @lucene.experimental */
137 public float freq() throws IOException {
138 throw new UnsupportedOperationException(this + " does not implement freq()");
142 * A callback to gather information from a scorer and its sub-scorers. Each
143 * the top-level scorer as well as each of its sub-scorers are passed to
144 * either one of the visit methods depending on their boolean relationship in
146 * @lucene.experimental
148 public static abstract class ScorerVisitor<P extends Query, C extends Query, S extends Scorer> {
150 * Invoked for all optional scorer
152 * @param parent the parent query of the child query or <code>null</code> if the child is a top-level query
153 * @param child the query of the currently visited scorer
154 * @param scorer the current scorer
156 public void visitOptional(P parent, C child, S scorer) {}
159 * Invoked for all required scorer
161 * @param parent the parent query of the child query or <code>null</code> if the child is a top-level query
162 * @param child the query of the currently visited scorer
163 * @param scorer the current scorer
165 public void visitRequired(P parent, C child, S scorer) {}
168 * Invoked for all prohibited scorer
170 * @param parent the parent query of the child query or <code>null</code> if the child is a top-level query
171 * @param child the query of the currently visited scorer
172 * @param scorer the current scorer
174 public void visitProhibited(P parent, C child, S scorer) {}
178 * Expert: call this to gather details for all sub-scorers for this query.
179 * This can be used, in conjunction with a custom {@link Collector} to gather
180 * details about how each sub-query matched the current hit.
182 * @param visitor a callback executed for each sub-scorer
183 * @lucene.experimental
185 public void visitScorers(ScorerVisitor<Query, Query, Scorer> visitor) {
186 visitSubScorers(null, Occur.MUST/*must id default*/, visitor);
190 * {@link Scorer} subclasses should implement this method if the subclass
191 * itself contains multiple scorers to support gathering details for
192 * sub-scorers via {@link ScorerVisitor}
194 * Note: this method will throw {@link UnsupportedOperationException} if no
195 * associated {@link Weight} instance is provided to
196 * {@link #Scorer(Weight)}
199 * @lucene.experimental
201 protected void visitSubScorers(Query parent, Occur relationship,
202 ScorerVisitor<Query, Query, Scorer> visitor) {
204 throw new UnsupportedOperationException();
206 final Query q = weight.getQuery();
207 switch (relationship) {
209 visitor.visitRequired(parent, q, this);
212 visitor.visitProhibited(parent, q, this);
215 visitor.visitOptional(parent, q, this);