当前位置:网站首页>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
边栏推荐
- Beginners use Minio
- Jeecg request URL signature
- Circuit, packet and message exchange
- [set theory] order relation (partial order relation | partial order set | example of partial order set)
- 专题 | 同步 异步
- Advanced API (UDP connection & map set & collection set)
- 【无标题】
- Deep learning parameter initialization (I) Xavier initialization with code
- TCP cumulative acknowledgement and window value update
- Common analysis with criteria method
猜你喜欢

HCIA notes

Margin left: -100% understanding in the Grail layout

Topic | synchronous asynchronous

SecureCRT取消Session记录的密码

Reconnaissance et détection d'images - Notes

FileInputStream and fileoutputstream

Use of generics

Pat grade a real problem 1166

docker建立mysql:5.7版本指定路径挂载不上。

Arduino Serial系列函数 有关print read 的总结
随机推荐
Advanced APL (realize group chat room)
[plus de détails] dernière entrevue complète redis (50)
I. D3.js hello world
[set theory] Stirling subset number (Stirling subset number concept | ball model | Stirling subset number recurrence formula | binary relationship refinement relationship of division)
C WinForm framework
The difference between typescript let and VaR
[untitled]
2. E-commerce tool cefsharp autojs MySQL Alibaba cloud react C RPA automated script, open source log
Vertx restful style web router
JS monitors empty objects and empty references
Hash table, generic
Comparison of advantages and disadvantages between most complete SQL and NoSQL
SecureCRT取消Session记录的密码
Unified handling and interception of exception exceptions of vertx
【已解决】SQLException: Invalid value for getInt() - ‘田鹏‘
Hello world of vertx
The embodiment of generics in inheritance and wildcards
PgSQL converts string to double type (to_number())
你开发数据API最快多长时间?我1分钟就足够了
VMware virtual machine installation