36
36
import org .apache .lucene .search .Scorer ;
37
37
import org .apache .lucene .search .BulkScorer ;
38
38
import org .apache .lucene .util .Bits ;
39
- import org .elasticsearch .ElasticsearchException ;
40
39
import org .elasticsearch .Version ;
41
40
import org .elasticsearch .script .ScoreScript ;
42
41
import org .elasticsearch .script .ScoreScript .ExplanationHolder ;
@@ -85,7 +84,7 @@ public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float bo
85
84
}
86
85
boolean needsScore = scriptBuilder .needs_score ();
87
86
ScoreMode subQueryScoreMode = needsScore ? ScoreMode .COMPLETE : ScoreMode .COMPLETE_NO_SCORES ;
88
- Weight subQueryWeight = subQuery .createWeight (searcher , subQueryScoreMode , boost );
87
+ Weight subQueryWeight = subQuery .createWeight (searcher , subQueryScoreMode , 1.0f );
89
88
90
89
return new Weight (this ){
91
90
@ Override
@@ -95,7 +94,7 @@ public BulkScorer bulkScorer(LeafReaderContext context) throws IOException {
95
94
if (subQueryBulkScorer == null ) {
96
95
return null ;
97
96
}
98
- return new ScriptScoreBulkScorer (subQueryBulkScorer , subQueryScoreMode , makeScoreScript (context ));
97
+ return new ScriptScoreBulkScorer (subQueryBulkScorer , subQueryScoreMode , makeScoreScript (context ), boost );
99
98
} else {
100
99
return super .bulkScorer (context );
101
100
}
@@ -112,7 +111,7 @@ public Scorer scorer(LeafReaderContext context) throws IOException {
112
111
if (subQueryScorer == null ) {
113
112
return null ;
114
113
}
115
- Scorer scriptScorer = new ScriptScorer (this , makeScoreScript (context ), subQueryScorer , subQueryScoreMode , null );
114
+ Scorer scriptScorer = new ScriptScorer (this , makeScoreScript (context ), subQueryScorer , subQueryScoreMode , boost , null );
116
115
if (minScore != null ) {
117
116
scriptScorer = new MinScoreScorer (this , scriptScorer , minScore );
118
117
}
@@ -127,11 +126,11 @@ public Explanation explain(LeafReaderContext context, int doc) throws IOExceptio
127
126
}
128
127
ExplanationHolder explanationHolder = new ExplanationHolder ();
129
128
Scorer scorer = new ScriptScorer (this , makeScoreScript (context ),
130
- subQueryWeight .scorer (context ), subQueryScoreMode , explanationHolder );
129
+ subQueryWeight .scorer (context ), subQueryScoreMode , 1f , explanationHolder );
131
130
int newDoc = scorer .iterator ().advance (doc );
132
131
assert doc == newDoc ; // subquery should have already matched above
133
- float score = scorer .score ();
134
-
132
+ float score = scorer .score (); // score without boost
133
+
135
134
Explanation explanation = explanationHolder .get (score , needsScore ? subQueryExplanation : null );
136
135
if (explanation == null ) {
137
136
// no explanation provided by user; give a simple one
@@ -143,7 +142,10 @@ public Explanation explain(LeafReaderContext context, int doc) throws IOExceptio
143
142
explanation = Explanation .match (score , desc );
144
143
}
145
144
}
146
-
145
+ if (boost != 1f ) {
146
+ explanation = Explanation .match (boost * explanation .getValue ().floatValue (), "Boosted score, product of:" ,
147
+ Explanation .match (boost , "boost" ), explanation );
148
+ }
147
149
if (minScore != null && minScore > explanation .getValue ().floatValue ()) {
148
150
explanation = Explanation .noMatch ("Score value is too low, expected at least " + minScore +
149
151
" but got " + explanation .getValue (), explanation );
@@ -203,16 +205,18 @@ public int hashCode() {
203
205
private static class ScriptScorer extends Scorer {
204
206
private final ScoreScript scoreScript ;
205
207
private final Scorer subQueryScorer ;
208
+ private final float boost ;
206
209
private final ExplanationHolder explanation ;
207
210
208
211
ScriptScorer (Weight weight , ScoreScript scoreScript , Scorer subQueryScorer ,
209
- ScoreMode subQueryScoreMode , ExplanationHolder explanation ) {
212
+ ScoreMode subQueryScoreMode , float boost , ExplanationHolder explanation ) {
210
213
super (weight );
211
214
this .scoreScript = scoreScript ;
212
215
if (subQueryScoreMode == ScoreMode .COMPLETE ) {
213
216
scoreScript .setScorer (subQueryScorer );
214
217
}
215
218
this .subQueryScorer = subQueryScorer ;
219
+ this .boost = boost ;
216
220
this .explanation = explanation ;
217
221
}
218
222
@@ -221,12 +225,13 @@ public float score() throws IOException {
221
225
int docId = docID ();
222
226
scoreScript .setDocument (docId );
223
227
float score = (float ) scoreScript .execute (explanation );
224
- if (score == Float . NEGATIVE_INFINITY || Float .isNaN (score )) {
225
- throw new ElasticsearchException (
226
- "script_score query returned an invalid score [" + score + "] for doc [" + docId + "]. " );
228
+ if (score < 0f || Float .isNaN (score )) {
229
+ throw new IllegalArgumentException ( "script_score script returned an invalid score [" + score + "] " +
230
+ "for doc [" + docId + "]. Must be a non-negative score! " );
227
231
}
228
- return score ;
232
+ return score * boost ;
229
233
}
234
+
230
235
@ Override
231
236
public int docID () {
232
237
return subQueryScorer .docID ();
@@ -247,15 +252,17 @@ public float getMaxScore(int upTo) {
247
252
private static class ScriptScorable extends Scorable {
248
253
private final ScoreScript scoreScript ;
249
254
private final Scorable subQueryScorer ;
255
+ private final float boost ;
250
256
private final ExplanationHolder explanation ;
251
257
252
258
ScriptScorable (ScoreScript scoreScript , Scorable subQueryScorer ,
253
- ScoreMode subQueryScoreMode , ExplanationHolder explanation ) {
259
+ ScoreMode subQueryScoreMode , float boost , ExplanationHolder explanation ) {
254
260
this .scoreScript = scoreScript ;
255
261
if (subQueryScoreMode == ScoreMode .COMPLETE ) {
256
262
scoreScript .setScorer (subQueryScorer );
257
263
}
258
264
this .subQueryScorer = subQueryScorer ;
265
+ this .boost = boost ;
259
266
this .explanation = explanation ;
260
267
}
261
268
@@ -264,11 +271,11 @@ public float score() throws IOException {
264
271
int docId = docID ();
265
272
scoreScript .setDocument (docId );
266
273
float score = (float ) scoreScript .execute (explanation );
267
- if (score == Float . NEGATIVE_INFINITY || Float .isNaN (score )) {
268
- throw new ElasticsearchException (
269
- "script_score query returned an invalid score [" + score + "] for doc [" + docId + "]. " );
274
+ if (score < 0f || Float .isNaN (score )) {
275
+ throw new IllegalArgumentException ( "script_score script returned an invalid score [" + score + "] " +
276
+ "for doc [" + docId + "]. Must be a non-negative score! " );
270
277
}
271
- return score ;
278
+ return score * boost ;
272
279
}
273
280
@ Override
274
281
public int docID () {
@@ -284,11 +291,13 @@ private static class ScriptScoreBulkScorer extends BulkScorer {
284
291
private final BulkScorer subQueryBulkScorer ;
285
292
private final ScoreMode subQueryScoreMode ;
286
293
private final ScoreScript scoreScript ;
294
+ private final float boost ;
287
295
288
- ScriptScoreBulkScorer (BulkScorer subQueryBulkScorer , ScoreMode subQueryScoreMode , ScoreScript scoreScript ) {
296
+ ScriptScoreBulkScorer (BulkScorer subQueryBulkScorer , ScoreMode subQueryScoreMode , ScoreScript scoreScript , float boost ) {
289
297
this .subQueryBulkScorer = subQueryBulkScorer ;
290
298
this .subQueryScoreMode = subQueryScoreMode ;
291
299
this .scoreScript = scoreScript ;
300
+ this .boost = boost ;
292
301
}
293
302
294
303
@ Override
@@ -300,7 +309,7 @@ private LeafCollector wrapCollector(LeafCollector collector) {
300
309
return new FilterLeafCollector (collector ) {
301
310
@ Override
302
311
public void setScorer (Scorable scorer ) throws IOException {
303
- in .setScorer (new ScriptScorable (scoreScript , scorer , subQueryScoreMode , null ));
312
+ in .setScorer (new ScriptScorable (scoreScript , scorer , subQueryScoreMode , boost , null ));
304
313
}
305
314
};
306
315
}
0 commit comments