当前位置:网站首页>lucene scorer
lucene scorer
2022-07-03 07:29:00 【chuanyangwang】
With ReqExclScorer Here's an example :
public ReqExclScorer(Scorer reqScorer, Scorer exclScorer) {
super(reqScorer.weight);
this.reqScorer = reqScorer;
reqTwoPhaseIterator = reqScorer.twoPhaseIterator();
if (reqTwoPhaseIterator == null) {
reqApproximation = reqScorer.iterator();
} else {
reqApproximation = reqTwoPhaseIterator.approximation();
}
exclTwoPhaseIterator = exclScorer.twoPhaseIterator();
if (exclTwoPhaseIterator == null) {
exclApproximation = exclScorer.iterator();
} else {
exclApproximation = exclTwoPhaseIterator.approximation();
}
}
@Override
public DocIdSetIterator iterator() {
return TwoPhaseIterator.asDocIdSetIterator(twoPhaseIterator());
}
@Override
public TwoPhaseIterator twoPhaseIterator() {
final float matchCost = matchCost(reqApproximation, reqTwoPhaseIterator, exclApproximation, exclTwoPhaseIterator);
if (reqTwoPhaseIterator == null
|| (exclTwoPhaseIterator != null && reqTwoPhaseIterator.matchCost() <= exclTwoPhaseIterator.matchCost())) {
// reqTwoPhaseIterator is LESS costly than exclTwoPhaseIterator, check it first
return new TwoPhaseIterator(reqApproximation) {
@Override
public boolean matches() throws IOException {
final int doc = reqApproximation.docID();
// check if the doc is not excluded
int exclDoc = exclApproximation.docID();
if (exclDoc < doc) {
exclDoc = exclApproximation.advance(doc);
}
if (exclDoc != doc) {
return matchesOrNull(reqTwoPhaseIterator);
}
return matchesOrNull(reqTwoPhaseIterator) && !matchesOrNull(exclTwoPhaseIterator);
}
@Override
public float matchCost() {
return matchCost;
}
};
} else {
// reqTwoPhaseIterator is MORE costly than exclTwoPhaseIterator, check it last
return new TwoPhaseIterator(reqApproximation) {
@Override
public boolean matches() throws IOException {
final int doc = reqApproximation.docID();
// check if the doc is not excluded
int exclDoc = exclApproximation.docID();
if (exclDoc < doc) {
exclDoc = exclApproximation.advance(doc);
}
if (exclDoc != doc) {
return matchesOrNull(reqTwoPhaseIterator);
}
return !matchesOrNull(exclTwoPhaseIterator) && matchesOrNull(reqTwoPhaseIterator);
}
@Override
public float matchCost() {
return matchCost;
}
};
}
}
1. The scoring process uses a combination pattern
2. Layers pass between layers iterator To transfer data
org.apache.lucene.search.Boolean2ScorerSupplier Of 3 Two basic methods
req:
- If requiredNoScoring and requiredScoring The total number of is 1
- get req
- If you don't need to score, you can return directly req
- If requiredScoring If it is empty, it will be converted into a filter
- If the sum of the two sets is greater than 1
- Generate two Scorer Set requiredScorers and scoringScorers
- If scoreMode by TOP_SCORES And scoringScorers Of size Greater than 1 Then born blockMaxScorer, If requiredScorers Of size by 0 Then return directly blockMaxScorer
- If requiredScorers Of size Greater than 0 Generate a ConjunctionScorer
private Scorer req(Collection<ScorerSupplier> requiredNoScoring, Collection<ScorerSupplier> requiredScoring, long leadCost) throws IOException {
if (requiredNoScoring.size() + requiredScoring.size() == 1) {
Scorer req = (requiredNoScoring.isEmpty() ? requiredScoring : requiredNoScoring).iterator().next().get(leadCost);
if (scoreMode.needsScores() == false) {
return req;
}
if (requiredScoring.isEmpty()) {
// Scores are needed but we only have a filter clause
// BooleanWeight expects that calling score() is ok so we need to wrap
// to prevent score() from being propagated
return new FilterScorer(req) {
@Override
public float score() throws IOException {
return 0f;
}
@Override
public float getMaxScore(int upTo) throws IOException {
return 0f;
}
};
}
return req;
} else {
List<Scorer> requiredScorers = new ArrayList<>();
List<Scorer> scoringScorers = new ArrayList<>();
for (ScorerSupplier s : requiredNoScoring) {
requiredScorers.add(s.get(leadCost));
}
for (ScorerSupplier s : requiredScoring) {
Scorer scorer = s.get(leadCost);
scoringScorers.add(scorer);
}
if (scoreMode == ScoreMode.TOP_SCORES && scoringScorers.size() > 1) {
// Will all scoringScorers Combine into BlockMaxConjunctionScorer
Scorer blockMaxScorer = new BlockMaxConjunctionScorer(weight, scoringScorers);
if (requiredScorers.isEmpty()) {
return blockMaxScorer;
}
scoringScorers = Collections.singletonList(blockMaxScorer);
}
// take scoringScorers Put in requiredScorers in , In that case requiredScorers Inevitable inclusion scoringScorers
requiredScorers.addAll(scoringScorers);
return new ConjunctionScorer(weight, requiredScorers, scoringScorers);
}
}
excl
- If prohibited Empty to return directly to main
- If prohibited If it is not empty, return ReqExclScorer
private Scorer excl(Scorer main, Collection<ScorerSupplier> prohibited, long leadCost) throws IOException {
if (prohibited.isEmpty()) {
return main;
} else {
return new ReqExclScorer(main, opt(prohibited, 1, ScoreMode.COMPLETE_NO_SCORES, leadCost));
}
}
opt
- If optional Of size by 1 Go straight back to
- If it is greater than 1
- Generate optionalScorers, Use optional, Generate score Into it
- If minShouldMatch Greater than 1 Generate MinShouldMatchSumScorer
- otherwise And scoreMode by TOP_SCORES Generate a WANDScorer
- Otherwise it generates DisjunctionSumScorer
private Scorer opt(Collection<ScorerSupplier> optional, int minShouldMatch,
ScoreMode scoreMode, long leadCost) throws IOException {
if (optional.size() == 1) {
return optional.iterator().next().get(leadCost);
} else {
final List<Scorer> optionalScorers = new ArrayList<>();
for (ScorerSupplier scorer : optional) {
optionalScorers.add(scorer.get(leadCost));
}
if (minShouldMatch > 1) {
return new MinShouldMatchSumScorer(weight, optionalScorers, minShouldMatch);
} else if (scoreMode == ScoreMode.TOP_SCORES) {
return new WANDScorer(weight, optionalScorers);
} else {
return new DisjunctionSumScorer(weight, optionalScorers, scoreMode);
}
}
}
getInternal
- Calculation cost
- If should If it is blank, return excel
- If filter and must If it is blank, return excel
- If minShouldMatch Greater than 0 Then return to ConjunctionScorer
- Otherwise return to ReqOptSumScorer
private Scorer getInternal(long leadCost) throws IOException {
// three cases: conjunction, disjunction, or mix
leadCost = Math.min(leadCost, cost());
// pure conjunction
if (subs.get(Occur.SHOULD).isEmpty()) {
return excl(req(subs.get(Occur.FILTER), subs.get(Occur.MUST), leadCost), subs.get(Occur.MUST_NOT), leadCost);
}
// pure disjunction
if (subs.get(Occur.FILTER).isEmpty() && subs.get(Occur.MUST).isEmpty()) {
return excl(opt(subs.get(Occur.SHOULD), minShouldMatch, scoreMode, leadCost), subs.get(Occur.MUST_NOT), leadCost);
}
// conjunction-disjunction mix:
// we create the required and optional pieces, and then
// combine the two: if minNrShouldMatch > 0, then it's a conjunction: because the
// optional side must match. otherwise it's required + optional
if (minShouldMatch > 0) {
Scorer req = excl(req(subs.get(Occur.FILTER), subs.get(Occur.MUST), leadCost), subs.get(Occur.MUST_NOT), leadCost);
Scorer opt = opt(subs.get(Occur.SHOULD), minShouldMatch, scoreMode, leadCost);
return new ConjunctionScorer(weight, Arrays.asList(req, opt), Arrays.asList(req, opt));
} else {
assert scoreMode.needsScores();
return new ReqOptSumScorer(
excl(req(subs.get(Occur.FILTER), subs.get(Occur.MUST), leadCost), subs.get(Occur.MUST_NOT), leadCost),
opt(subs.get(Occur.SHOULD), minShouldMatch, scoreMode, leadCost), scoreMode);
}
}
org.apache.lucene.search.BooleanWeight scorerSupplier
public ScorerSupplier scorerSupplier(LeafReaderContext context) throws IOException {
int minShouldMatch = query.getMinimumNumberShouldMatch();
final Map<Occur, Collection<ScorerSupplier>> scorers = new EnumMap<>(Occur.class);
for (Occur occur : Occur.values()) {
scorers.put(occur, new ArrayList<>());
}
for (WeightedBooleanClause wc : weightedClauses) {
Weight w = wc.weight;
BooleanClause c = wc.clause;
// Recursively generate the next level scorerSupplier
ScorerSupplier subScorer = w.scorerSupplier(context);
if (subScorer == null) {
if (c.isRequired()) {
return null;
}
} else {
scorers.get(c.getOccur()).add(subScorer);
}
}
// scorer simplifications:
if (scorers.get(Occur.SHOULD).size() == minShouldMatch) {
// any optional clauses are in fact required
scorers.get(Occur.MUST).addAll(scorers.get(Occur.SHOULD));
scorers.get(Occur.SHOULD).clear();
minShouldMatch = 0;
}
if (scorers.get(Occur.FILTER).isEmpty() && scorers.get(Occur.MUST).isEmpty() && scorers.get(Occur.SHOULD).isEmpty()) {
// no required and optional clauses.
return null;
} else if (scorers.get(Occur.SHOULD).size() < minShouldMatch) {
// either >1 req scorer, or there are 0 req scorers and at least 1
// optional scorer. Therefore if there are not enough optional scorers
// no documents will be matched by the query
return null;
}
return new Boolean2ScorerSupplier(this, scorers, scoreMode, minShouldMatch);
}
ConjunctionDISI Will be based on cost Sort
final DocIdSetIterator lead1, lead2;
final DocIdSetIterator[] others;
private ConjunctionDISI(List<? extends DocIdSetIterator> iterators) {
assert iterators.size() >= 2;
// Sort the array the first time to allow the least frequent DocsEnum to
// lead the matching.
CollectionUtil.timSort(iterators, new Comparator<DocIdSetIterator>() {
@Override
public int compare(DocIdSetIterator o1, DocIdSetIterator o2) {
return Long.compare(o1.cost(), o2.cost());
}
});
lead1 = iterators.get(0);
lead2 = iterators.get(1);
others = iterators.subList(2, iterators.size()).toArray(new DocIdSetIterator[0]);
}
Important classes
DefaultBulkScorer
scorer The wrapper class , The functions and top scoring
边栏推荐
- OSI knowledge sorting
- Visit Google homepage to display this page, which cannot be displayed
- "Baidu Cup" CTF game 2017 February, Web: blast-1
- TreeMap
- Common APIs
- Longest common prefix and
- I. D3.js hello world
- Interview questions about producers and consumers (important)
- Common methods of file class
- Image recognition and detection -- Notes
猜你喜欢
随机推荐
When MySQL inserts Chinese into the database, there is a diamond question mark garbled code
Talk about floating
Hash table, generic
Industrial resilience
树莓派更新工具链
专题 | 同步 异步
Unified handling and interception of exception exceptions of vertx
Deep learning parameter initialization (I) Xavier initialization with code
JS monitors empty objects and empty references
Summary of abnormal mechanism of interview
Chapter VI - Containers
PgSQL converts string to double type (to_number())
OSI knowledge sorting
SharePoint modification usage analysis report is more than 30 days
New stills of Lord of the rings: the ring of strength: the caster of the ring of strength appears
List exercises after class
Qtip2 solves the problem of too many texts
pgAdmin 4 v6.11 发布,PostgreSQL 开源图形化管理工具
[solved] win10 cannot find a solution to the local group policy editor
Grpc message sending of vertx