use of org.opensearch.common.lucene.search.function.FunctionScoreQuery in project OpenSearch by opensearch-project.
the class FunctionScoreQueryBuilder method doToQuery.
@Override
protected Query doToQuery(QueryShardContext context) throws IOException {
ScoreFunction[] filterFunctions = new ScoreFunction[filterFunctionBuilders.length];
int i = 0;
for (FilterFunctionBuilder filterFunctionBuilder : filterFunctionBuilders) {
ScoreFunction scoreFunction = filterFunctionBuilder.getScoreFunction().toFunction(context);
final QueryBuilder builder = filterFunctionBuilder.getFilter();
if (builder.getName().equals(MatchAllQueryBuilder.NAME)) {
filterFunctions[i++] = scoreFunction;
} else {
Query filter = builder.toQuery(context);
filterFunctions[i++] = new FunctionScoreQuery.FilterScoreFunction(filter, scoreFunction, builder.queryName());
}
}
final QueryBuilder builder = this.query;
Query query = builder.toQuery(context);
if (query == null) {
query = new MatchAllDocsQuery();
}
CombineFunction boostMode = this.boostMode == null ? DEFAULT_BOOST_MODE : this.boostMode;
// handle cases where only one score function and no filter was provided. In this case we create a FunctionScoreQuery.
if (filterFunctions.length == 0) {
return new FunctionScoreQuery(query, builder.queryName(), minScore, maxBoost);
} else if (filterFunctions.length == 1 && filterFunctions[0] instanceof FunctionScoreQuery.FilterScoreFunction == false) {
return new FunctionScoreQuery(query, builder.queryName(), filterFunctions[0], boostMode, minScore, maxBoost);
}
// in all other cases we create a FunctionScoreQuery with filters
return new FunctionScoreQuery(query, builder.queryName(), scoreMode, filterFunctions, boostMode, minScore, maxBoost);
}
use of org.opensearch.common.lucene.search.function.FunctionScoreQuery in project OpenSearch by opensearch-project.
the class FunctionScoreEquivalenceTests method testMinScoreAllExcluded.
public void testMinScoreAllExcluded() throws Exception {
Term term = randomTerm();
Query query = new TermQuery(term);
FunctionScoreQuery fsq = new FunctionScoreQuery(query, Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY);
assertSameScores(new MatchNoDocsQuery(), fsq);
}
use of org.opensearch.common.lucene.search.function.FunctionScoreQuery in project OpenSearch by opensearch-project.
the class FunctionScoreEquivalenceTests method testMinScoreAllIncluded.
public void testMinScoreAllIncluded() throws Exception {
Term term = randomTerm();
Query query = new TermQuery(term);
FunctionScoreQuery fsq = new FunctionScoreQuery(query, null, Float.POSITIVE_INFINITY);
assertSameScores(query, fsq);
FunctionScoreQuery ffsq = new FunctionScoreQuery(query, 0f, Float.POSITIVE_INFINITY);
assertSameScores(query, ffsq);
}
use of org.opensearch.common.lucene.search.function.FunctionScoreQuery in project OpenSearch by opensearch-project.
the class FunctionScoreQueryBuilderTests method testCustomWeightFactorQueryBuilderWithFunctionScore.
public void testCustomWeightFactorQueryBuilderWithFunctionScore() throws IOException {
QueryShardContext context = createShardContext();
Query parsedQuery = parseQuery(functionScoreQuery(termQuery(KEYWORD_FIELD_NAME, "banon"), weightFactorFunction(1.3f))).rewrite(context).toQuery(context);
assertThat(parsedQuery, instanceOf(FunctionScoreQuery.class));
FunctionScoreQuery functionScoreQuery = (FunctionScoreQuery) parsedQuery;
assertThat(((TermQuery) functionScoreQuery.getSubQuery()).getTerm(), equalTo(new Term(KEYWORD_FIELD_NAME, "banon")));
assertThat((double) (functionScoreQuery.getFunctions()[0]).getWeight(), closeTo(1.3, 0.001));
}
use of org.opensearch.common.lucene.search.function.FunctionScoreQuery in project OpenSearch by opensearch-project.
the class FunctionScoreTests method testSimpleWeightedFunction.
public void testSimpleWeightedFunction() throws IOException, ExecutionException, InterruptedException {
int numFunctions = randomIntBetween(1, 3);
float[] weights = randomPositiveFloats(numFunctions);
double[] scores = randomPositiveDoubles(numFunctions);
ScoreFunctionStub[] scoreFunctionStubs = new ScoreFunctionStub[numFunctions];
for (int i = 0; i < numFunctions; i++) {
scoreFunctionStubs[i] = new ScoreFunctionStub(scores[i]);
}
WeightFactorFunction[] weightFunctionStubs = new WeightFactorFunction[numFunctions];
for (int i = 0; i < numFunctions; i++) {
weightFunctionStubs[i] = new WeightFactorFunction(weights[i], scoreFunctionStubs[i]);
}
FunctionScoreQuery functionScoreQueryWithWeights = getFiltersFunctionScoreQuery(FunctionScoreQuery.ScoreMode.MULTIPLY, CombineFunction.REPLACE, weightFunctionStubs);
TopDocs topDocsWithWeights = searcher.search(functionScoreQueryWithWeights, 1);
float scoreWithWeight = topDocsWithWeights.scoreDocs[0].score;
double score = 1;
for (int i = 0; i < weights.length; i++) {
score *= weights[i] * scores[i];
}
assertThat(scoreWithWeight / (float) score, is(1f));
float explainedScore = getExplanation(searcher, functionScoreQueryWithWeights).getValue().floatValue();
assertThat(explainedScore / scoreWithWeight, is(1f));
functionScoreQueryWithWeights = getFiltersFunctionScoreQuery(FunctionScoreQuery.ScoreMode.SUM, CombineFunction.REPLACE, weightFunctionStubs);
topDocsWithWeights = searcher.search(functionScoreQueryWithWeights, 1);
scoreWithWeight = topDocsWithWeights.scoreDocs[0].score;
double sum = 0;
for (int i = 0; i < weights.length; i++) {
sum += weights[i] * scores[i];
}
assertThat(scoreWithWeight / (float) sum, is(1f));
explainedScore = getExplanation(searcher, functionScoreQueryWithWeights).getValue().floatValue();
assertThat(explainedScore / scoreWithWeight, is(1f));
functionScoreQueryWithWeights = getFiltersFunctionScoreQuery(FunctionScoreQuery.ScoreMode.AVG, CombineFunction.REPLACE, weightFunctionStubs);
topDocsWithWeights = searcher.search(functionScoreQueryWithWeights, 1);
scoreWithWeight = topDocsWithWeights.scoreDocs[0].score;
double norm = 0;
sum = 0;
for (int i = 0; i < weights.length; i++) {
norm += weights[i];
sum += weights[i] * scores[i];
}
assertThat(scoreWithWeight / (float) (sum / norm), is(1f));
explainedScore = getExplanation(searcher, functionScoreQueryWithWeights).getValue().floatValue();
assertThat(explainedScore / scoreWithWeight, is(1f));
functionScoreQueryWithWeights = getFiltersFunctionScoreQuery(FunctionScoreQuery.ScoreMode.MIN, CombineFunction.REPLACE, weightFunctionStubs);
topDocsWithWeights = searcher.search(functionScoreQueryWithWeights, 1);
scoreWithWeight = topDocsWithWeights.scoreDocs[0].score;
double min = Double.POSITIVE_INFINITY;
for (int i = 0; i < weights.length; i++) {
min = Math.min(min, weights[i] * scores[i]);
}
assertThat(scoreWithWeight / (float) min, is(1f));
explainedScore = getExplanation(searcher, functionScoreQueryWithWeights).getValue().floatValue();
assertThat(explainedScore / scoreWithWeight, is(1f));
functionScoreQueryWithWeights = getFiltersFunctionScoreQuery(FunctionScoreQuery.ScoreMode.MAX, CombineFunction.REPLACE, weightFunctionStubs);
topDocsWithWeights = searcher.search(functionScoreQueryWithWeights, 1);
scoreWithWeight = topDocsWithWeights.scoreDocs[0].score;
double max = Double.NEGATIVE_INFINITY;
for (int i = 0; i < weights.length; i++) {
max = Math.max(max, weights[i] * scores[i]);
}
assertThat(scoreWithWeight / (float) max, is(1f));
explainedScore = getExplanation(searcher, functionScoreQueryWithWeights).getValue().floatValue();
assertThat(explainedScore / scoreWithWeight, is(1f));
}
Aggregations