use of org.opensearch.script.ScoreScript in project OpenSearch by opensearch-project.
the class ScriptScoreFunction method getLeafScoreFunction.
@Override
public LeafScoreFunction getLeafScoreFunction(LeafReaderContext ctx) throws IOException {
final ScoreScript leafScript = script.newInstance(ctx);
final CannedScorer scorer = new CannedScorer();
leafScript.setScorer(scorer);
leafScript._setIndexName(indexName);
leafScript._setShard(shardId);
leafScript._setIndexVersion(indexVersion);
return new LeafScoreFunction() {
@Override
public double score(int docId, float subQueryScore) throws IOException {
leafScript.setDocument(docId);
scorer.docid = docId;
scorer.score = subQueryScore;
double result = leafScript.execute(null);
if (result < 0f) {
throw new IllegalArgumentException("script score function must not produce negative scores, but got: [" + result + "]");
}
return result;
}
@Override
public Explanation explainScore(int docId, Explanation subQueryScore) throws IOException {
Explanation exp;
if (leafScript instanceof ExplainableScoreScript) {
leafScript.setDocument(docId);
scorer.docid = docId;
scorer.score = subQueryScore.getValue().floatValue();
exp = ((ExplainableScoreScript) leafScript).explain(subQueryScore, functionName);
} else {
double score = score(docId, subQueryScore.getValue().floatValue());
// info about params already included in sScript
String explanation = "script score function" + Functions.nameOrEmptyFunc(functionName) + ", computed with script:\"" + sScript + "\"";
Explanation scoreExp = Explanation.match(subQueryScore.getValue(), "_score: ", subQueryScore);
return Explanation.match((float) score, explanation, scoreExp);
}
return exp;
}
};
}
use of org.opensearch.script.ScoreScript in project OpenSearch by opensearch-project.
the class ScriptScoreQuery method createWeight.
@Override
public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
if (scoreMode == ScoreMode.COMPLETE_NO_SCORES && minScore == null) {
return subQuery.createWeight(searcher, scoreMode, boost);
}
boolean needsScore = scriptBuilder.needs_score();
ScoreMode subQueryScoreMode = needsScore ? ScoreMode.COMPLETE : ScoreMode.COMPLETE_NO_SCORES;
Weight subQueryWeight = subQuery.createWeight(searcher, subQueryScoreMode, 1.0f);
return new Weight(this) {
@Override
public BulkScorer bulkScorer(LeafReaderContext context) throws IOException {
if (minScore == null) {
final BulkScorer subQueryBulkScorer = subQueryWeight.bulkScorer(context);
if (subQueryBulkScorer == null) {
return null;
}
return new ScriptScoreBulkScorer(subQueryBulkScorer, subQueryScoreMode, makeScoreScript(context), boost);
} else {
return super.bulkScorer(context);
}
}
@Override
public void extractTerms(Set<Term> terms) {
subQueryWeight.extractTerms(terms);
}
@Override
public Scorer scorer(LeafReaderContext context) throws IOException {
Scorer subQueryScorer = subQueryWeight.scorer(context);
if (subQueryScorer == null) {
return null;
}
Scorer scriptScorer = new ScriptScorer(this, makeScoreScript(context), subQueryScorer, subQueryScoreMode, boost, null);
if (minScore != null) {
scriptScorer = new MinScoreScorer(this, scriptScorer, minScore);
}
return scriptScorer;
}
@Override
public Explanation explain(LeafReaderContext context, int doc) throws IOException {
Explanation subQueryExplanation = Functions.explainWithName(subQueryWeight.explain(context, doc), queryName);
if (subQueryExplanation.isMatch() == false) {
return subQueryExplanation;
}
ExplanationHolder explanationHolder = new ExplanationHolder();
Scorer scorer = new ScriptScorer(this, makeScoreScript(context), subQueryWeight.scorer(context), subQueryScoreMode, 1f, explanationHolder);
int newDoc = scorer.iterator().advance(doc);
// subquery should have already matched above
assert doc == newDoc;
// score without boost
float score = scorer.score();
Explanation explanation = explanationHolder.get(score, needsScore ? subQueryExplanation : null);
if (explanation == null) {
// no explanation provided by user; give a simple one
String desc = "script score function, computed with script:\"" + script + "\"";
if (needsScore) {
Explanation scoreExp = Explanation.match(subQueryExplanation.getValue(), "_score: ", subQueryExplanation);
explanation = Explanation.match(score, desc, scoreExp);
} else {
explanation = Explanation.match(score, desc);
}
}
if (boost != 1f) {
explanation = Explanation.match(boost * explanation.getValue().floatValue(), "Boosted score, product of:", Explanation.match(boost, "boost"), explanation);
}
if (minScore != null && minScore > explanation.getValue().floatValue()) {
explanation = Explanation.noMatch("Score value is too low, expected at least " + minScore + " but got " + explanation.getValue(), explanation);
}
return explanation;
}
private ScoreScript makeScoreScript(LeafReaderContext context) throws IOException {
final ScoreScript scoreScript = scriptBuilder.newInstance(context);
scoreScript._setIndexName(indexName);
scoreScript._setShard(shardId);
scoreScript._setIndexVersion(indexVersion);
return scoreScript;
}
@Override
public boolean isCacheable(LeafReaderContext ctx) {
// If minScore is not null, then matches depend on statistics of the top-level reader.
return minScore == null;
}
};
}
use of org.opensearch.script.ScoreScript in project OpenSearch by opensearch-project.
the class ScriptScoreQueryTests method newFactory.
private ScoreScript.LeafFactory newFactory(Script script, boolean needsScore, Function<ScoreScript.ExplanationHolder, Double> function) {
SearchLookup lookup = mock(SearchLookup.class);
LeafSearchLookup leafLookup = mock(LeafSearchLookup.class);
when(lookup.getLeafSearchLookup(any())).thenReturn(leafLookup);
return new ScoreScript.LeafFactory() {
@Override
public boolean needs_score() {
return needsScore;
}
@Override
public ScoreScript newInstance(LeafReaderContext ctx) throws IOException {
return new ScoreScript(script.getParams(), lookup, leafReaderContext) {
@Override
public double execute(ExplanationHolder explanation) {
return function.apply(explanation);
}
};
}
};
}
Aggregations