Search in sources :

Example 1 with ScoreScript

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;
        }
    };
}
Also used : ScoreScript(org.opensearch.script.ScoreScript) ExplainableScoreScript(org.opensearch.script.ExplainableScoreScript) Explanation(org.apache.lucene.search.Explanation) ExplainableScoreScript(org.opensearch.script.ExplainableScoreScript)

Example 2 with ScoreScript

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;
        }
    };
}
Also used : ScoreMode(org.apache.lucene.search.ScoreMode) Set(java.util.Set) ScoreScript(org.opensearch.script.ScoreScript) Explanation(org.apache.lucene.search.Explanation) BulkScorer(org.apache.lucene.search.BulkScorer) Scorer(org.apache.lucene.search.Scorer) ExplanationHolder(org.opensearch.script.ScoreScript.ExplanationHolder) BulkScorer(org.apache.lucene.search.BulkScorer) Weight(org.apache.lucene.search.Weight) LeafReaderContext(org.apache.lucene.index.LeafReaderContext)

Example 3 with ScoreScript

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);
                }
            };
        }
    };
}
Also used : ScoreScript(org.opensearch.script.ScoreScript) LeafReaderContext(org.apache.lucene.index.LeafReaderContext) LeafSearchLookup(org.opensearch.search.lookup.LeafSearchLookup) LeafSearchLookup(org.opensearch.search.lookup.LeafSearchLookup) SearchLookup(org.opensearch.search.lookup.SearchLookup)

Aggregations

ScoreScript (org.opensearch.script.ScoreScript)3 LeafReaderContext (org.apache.lucene.index.LeafReaderContext)2 Explanation (org.apache.lucene.search.Explanation)2 Set (java.util.Set)1 BulkScorer (org.apache.lucene.search.BulkScorer)1 ScoreMode (org.apache.lucene.search.ScoreMode)1 Scorer (org.apache.lucene.search.Scorer)1 Weight (org.apache.lucene.search.Weight)1 ExplainableScoreScript (org.opensearch.script.ExplainableScoreScript)1 ExplanationHolder (org.opensearch.script.ScoreScript.ExplanationHolder)1 LeafSearchLookup (org.opensearch.search.lookup.LeafSearchLookup)1 SearchLookup (org.opensearch.search.lookup.SearchLookup)1