📄 customscorequery.java
字号:
if(valSrcExpls.length == 1) { return customExplain(doc, subQueryExpl, valSrcExpls[0]); } if (valSrcExpls.length == 0) { return subQueryExpl; } float valSrcScore = 1; for(int i = 0; i < valSrcExpls.length; i++) { valSrcScore *= valSrcExpls[i].getValue(); } Explanation exp = new Explanation( valSrcScore * subQueryExpl.getValue(), "custom score: product of:"); exp.addDetail(subQueryExpl); for(int i = 0; i < valSrcExpls.length; i++) { exp.addDetail(valSrcExpls[i]); } return exp; } /** * Explain the custom score. * Whenever overriding {@link #customScore(int, float, float)}, * this method should also be overridden to provide the correct explanation * for the part of the custom scoring. * * @param doc doc being explained. * @param subQueryExpl explanation for the sub-query part. * @param valSrcExpl explanation for the value source part. * @return an explanation for the custom score */ public Explanation customExplain(int doc, Explanation subQueryExpl, Explanation valSrcExpl) { float valSrcScore = 1; if (valSrcExpl != null) { valSrcScore *= valSrcExpl.getValue(); } Explanation exp = new Explanation( valSrcScore * subQueryExpl.getValue(), "custom score: product of:"); exp.addDetail(subQueryExpl); exp.addDetail(valSrcExpl); return exp; } //=========================== W E I G H T ============================ private class CustomWeight implements Weight { Similarity similarity; Weight subQueryWeight; Weight[] valSrcWeights; boolean qStrict; public CustomWeight(Searcher searcher) throws IOException { this.similarity = getSimilarity(searcher); this.subQueryWeight = subQuery.weight(searcher); this.subQueryWeight = subQuery.weight(searcher); this.valSrcWeights = new Weight[valSrcQueries.length]; for(int i = 0; i < valSrcQueries.length; i++) { this.valSrcWeights[i] = valSrcQueries[i].createWeight(searcher); } this.qStrict = strict; } /*(non-Javadoc) @see org.apache.lucene.search.Weight#getQuery() */ public Query getQuery() { return CustomScoreQuery.this; } /*(non-Javadoc) @see org.apache.lucene.search.Weight#getValue() */ public float getValue() { return getBoost(); } /*(non-Javadoc) @see org.apache.lucene.search.Weight#sumOfSquaredWeights() */ public float sumOfSquaredWeights() throws IOException { float sum = subQueryWeight.sumOfSquaredWeights(); for(int i = 0; i < valSrcWeights.length; i++) { if (qStrict) { valSrcWeights[i].sumOfSquaredWeights(); // do not include ValueSource part in the query normalization } else { sum += valSrcWeights[i].sumOfSquaredWeights(); } } sum *= getBoost() * getBoost(); // boost each sub-weight return sum ; } /*(non-Javadoc) @see org.apache.lucene.search.Weight#normalize(float) */ public void normalize(float norm) { norm *= getBoost(); // incorporate boost subQueryWeight.normalize(norm); for(int i = 0; i < valSrcWeights.length; i++) { if (qStrict) { valSrcWeights[i].normalize(1); // do not normalize the ValueSource part } else { valSrcWeights[i].normalize(norm); } } } /*(non-Javadoc) @see org.apache.lucene.search.Weight#scorer(org.apache.lucene.index.IndexReader) */ public Scorer scorer(IndexReader reader) throws IOException { Scorer subQueryScorer = subQueryWeight.scorer(reader); Scorer[] valSrcScorers = new Scorer[valSrcWeights.length]; for(int i = 0; i < valSrcScorers.length; i++) { valSrcScorers[i] = valSrcWeights[i].scorer(reader); } return new CustomScorer(similarity, reader, this, subQueryScorer, valSrcScorers); } /*(non-Javadoc) @see org.apache.lucene.search.Weight#explain(org.apache.lucene.index.IndexReader, int) */ public Explanation explain(IndexReader reader, int doc) throws IOException { return scorer(reader).explain(doc); } } //=========================== S C O R E R ============================ /** * A scorer that applies a (callback) function on scores of the subQuery. */ private class CustomScorer extends Scorer { private final CustomWeight weight; private final float qWeight; private Scorer subQueryScorer; private Scorer[] valSrcScorers; private IndexReader reader; private float vScores[]; // reused in score() to avoid allocating this array for each doc // constructor private CustomScorer(Similarity similarity, IndexReader reader, CustomWeight w, Scorer subQueryScorer, Scorer[] valSrcScorers) throws IOException { super(similarity); this.weight = w; this.qWeight = w.getValue(); this.subQueryScorer = subQueryScorer; this.valSrcScorers = valSrcScorers; this.reader = reader; this.vScores = new float[valSrcScorers.length]; } /*(non-Javadoc) @see org.apache.lucene.search.Scorer#next() */ public boolean next() throws IOException { boolean hasNext = subQueryScorer.next(); if(hasNext) { for(int i = 0; i < valSrcScorers.length; i++) { valSrcScorers[i].skipTo(subQueryScorer.doc()); } } return hasNext; } /*(non-Javadoc) @see org.apache.lucene.search.Scorer#doc() */ public int doc() { return subQueryScorer.doc(); } /*(non-Javadoc) @see org.apache.lucene.search.Scorer#score() */ public float score() throws IOException { for(int i = 0; i < valSrcScorers.length; i++) { vScores[i] = valSrcScorers[i].score(); } return qWeight * customScore(subQueryScorer.doc(), subQueryScorer.score(), vScores); } /*(non-Javadoc) @see org.apache.lucene.search.Scorer#skipTo(int) */ public boolean skipTo(int target) throws IOException { boolean hasNext = subQueryScorer.skipTo(target); if(hasNext) { for(int i = 0; i < valSrcScorers.length; i++) { valSrcScorers[i].skipTo(subQueryScorer.doc()); } } return hasNext; } /*(non-Javadoc) @see org.apache.lucene.search.Scorer#explain(int) */ public Explanation explain(int doc) throws IOException { Explanation subQueryExpl = weight.subQueryWeight.explain(reader,doc); if (!subQueryExpl.isMatch()) { return subQueryExpl; } // match Explanation[] valSrcExpls = new Explanation[valSrcScorers.length]; for(int i = 0; i < valSrcScorers.length; i++) { valSrcExpls[i] = valSrcScorers[i].explain(doc); } Explanation customExp = customExplain(doc,subQueryExpl,valSrcExpls); float sc = qWeight * customExp.getValue(); Explanation res = new ComplexExplanation( true, sc, CustomScoreQuery.this.toString() + ", product of:"); res.addDetail(customExp); res.addDetail(new Explanation(qWeight, "queryBoost")); // actually using the q boost as q weight (== weight value) return res; } } /*(non-Javadoc) @see org.apache.lucene.search.Query#createWeight(org.apache.lucene.search.Searcher) */ protected Weight createWeight(Searcher searcher) throws IOException { return new CustomWeight(searcher); } /** * Checks if this is strict custom scoring. * In strict custom scoring, the ValueSource part of does not participate in weight normalization. * This may be useful when one wants full control over how scores are modified, and does * not care about normalizing by the ValueSource part. * One particular case where this is useful if for testing this query. * <P> * Note: only has effect when the ValueSource part is not null. */ public boolean isStrict() { return strict; } /** * Set the strict mode of this query. * @param strict The strict mode to set. * @see #isStrict() */ public void setStrict(boolean strict) { this.strict = strict; } /** * A short name of this query, used in {@link #toString(String)}. */ public String name() { return "custom"; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -