📄 inaccuratebooleanscorer2.java
字号:
package org.apache.lucene.search;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import org.apache.lucene.util.InaccurateResultAggregation;
/**
* <p>
* Rewritten by caocao (http://www.caocao.name)
*
* <p>
* Most of source code in InaccurateBooleanScorer2 came from BooleanScorer2. It
* can't extends BooleanScorer2 because some parts of BooleanScorer2 are
* invisiable.
*/
/**
* An alternative to BooleanScorer2. <br>
* Uses ConjunctionScorer, DisjunctionScorer, ReqOptScorer and ReqExclScorer.
* <br>
* Implements skipTo(), and has no limitations on the numbers of added scorers.
* <br>
* Work out getInaccurateTopAggregation and getAccurateBottomAggregation to
* allow inaccurate query against huge index files with quick response and high
* volumn.
*/
public class InaccurateBooleanScorer2 extends Scorer {
private ArrayList requiredScorers = new ArrayList();
private ArrayList optionalScorers = new ArrayList();
private ArrayList prohibitedScorers = new ArrayList();
protected class ResultNode {
private int doc;
private float score;
public ResultNode(int doc, float score) {
super();
this.doc = doc;
this.score = score;
}
public int getDoc() {
return doc;
}
public void setDoc(int doc) {
this.doc = doc;
}
public float getScore() {
return score;
}
public void setScore(float score) {
this.score = score;
}
}
private class Coordinator {
int maxCoord = 0; // to be increased for each non prohibited scorer
private float[] coordFactors = null;
void init() { // use after all scorers have been added.
coordFactors = new float[maxCoord + 1];
Similarity sim = getSimilarity();
for (int i = 0; i <= maxCoord; i++) {
coordFactors[i] = sim.coord(i, maxCoord);
}
}
int nrMatchers; // to be increased by score() of match counting scorers.
void initDoc() {
nrMatchers = 0;
}
float coordFactor() {
return coordFactors[nrMatchers];
}
}
private final Coordinator coordinator;
protected int maxNumberOfDocs;
/**
* The scorer to which all scoring will be delegated, except for computing
* and using the coordination factor.
*/
private Scorer countingSumScorer = null;
/** The number of optionalScorers that need to match (if there are any) */
private final int minNrShouldMatch;
/**
* Create a BooleanScorer2.
*
* @param similarity
* The similarity to be used.
* @param minNrShouldMatch
* The minimum number of optional added scorers that should match
* during the search. In case no required scorers are added, at
* least one of the optional scorers will have to match during
* the search.
*/
public InaccurateBooleanScorer2(Similarity similarity,
int minNrShouldMatch, int maxNumberOfDocs) {
super(similarity);
if (minNrShouldMatch < 0) {
throw new IllegalArgumentException(
"Minimum number of optional scorers should not be negative");
}
coordinator = new Coordinator();
this.minNrShouldMatch = minNrShouldMatch;
this.maxNumberOfDocs = maxNumberOfDocs;
}
/**
* Create a BooleanScorer2. In no required scorers are added, at least one
* of the optional scorers will have to match during the search.
*
* @param similarity
* The similarity to be used.
*/
public InaccurateBooleanScorer2(Similarity similarity) {
this(similarity, 0, Integer.MAX_VALUE);
}
@SuppressWarnings("unchecked")
public void add(final Scorer scorer, boolean required, boolean prohibited) {
if (!prohibited) {
coordinator.maxCoord++;
}
if (required) {
if (prohibited) {
throw new IllegalArgumentException(
"scorer cannot be required and prohibited");
}
requiredScorers.add(scorer);
} else if (prohibited) {
prohibitedScorers.add(scorer);
} else {
optionalScorers.add(scorer);
}
}
/**
* Initialize the match counting scorer that sums all the scores.
* <p>
* When "counting" is used in a name it means counting the number of
* matching scorers.<br>
* When "sum" is used in a name it means score value summing over the
* matching scorers
*/
private void initCountingSumScorer() {
coordinator.init();
countingSumScorer = makeCountingSumScorer();
}
/** Count a scorer as a single match. */
private class SingleMatchScorer extends Scorer {
private Scorer scorer;
private int lastScoredDoc = -1;
SingleMatchScorer(Scorer scorer) {
super(scorer.getSimilarity());
this.scorer = scorer;
}
public float score() throws IOException {
if (this.doc() > lastScoredDoc) {
lastScoredDoc = this.doc();
coordinator.nrMatchers++;
}
return scorer.score();
}
public int doc() {
return scorer.doc();
}
public boolean next() throws IOException {
return scorer.next();
}
public boolean skipTo(int docNr) throws IOException {
return scorer.skipTo(docNr);
}
public Explanation explain(int docNr) throws IOException {
return scorer.explain(docNr);
}
}
private Scorer countingDisjunctionSumScorer(List scorers,
int minMrShouldMatch)
// each scorer from the list counted as a single matcher
{
return new DisjunctionSumScorer(scorers, minMrShouldMatch) {
private int lastScoredDoc = -1;
public float score() throws IOException {
if (this.doc() > lastScoredDoc) {
lastScoredDoc = this.doc();
coordinator.nrMatchers += super.nrMatchers;
}
return super.score();
}
};
}
private static Similarity defaultSimilarity = new DefaultSimilarity();
private Scorer countingConjunctionSumScorer(List requiredScorers) {
// each scorer from the list counted as a single matcher
final int requiredNrMatchers = requiredScorers.size();
ConjunctionScorer cs = new ConjunctionScorer(defaultSimilarity) {
private int lastScoredDoc = -1;
public float score() throws IOException {
if (this.doc() > lastScoredDoc) {
lastScoredDoc = this.doc();
coordinator.nrMatchers += requiredNrMatchers;
}
// All scorers match, so defaultSimilarity super.score() always
// has 1 as
// the coordination factor.
// Therefore the sum of the scores of the requiredScorers
// is used as score.
return super.score();
}
};
Iterator rsi = requiredScorers.iterator();
while (rsi.hasNext()) {
cs.add((Scorer) rsi.next());
}
return cs;
}
private Scorer dualConjunctionSumScorer(Scorer req1, Scorer req2) { // non
// counting.
@SuppressWarnings("unused")
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -