use of org.elasticsearch.common.lucene.search.function.WeightFactorFunction in project elasticsearch by elastic.
the class DefaultSearchContext method preProcess.
/**
* Should be called before executing the main query and after all other parameters have been set.
*/
@Override
public void preProcess(boolean rewrite) {
if (hasOnlySuggest()) {
return;
}
long from = from() == -1 ? 0 : from();
long size = size() == -1 ? 10 : size();
long resultWindow = from + size;
int maxResultWindow = indexService.getIndexSettings().getMaxResultWindow();
if (resultWindow > maxResultWindow) {
if (scrollContext == null) {
throw new QueryPhaseExecutionException(this, "Result window is too large, from + size must be less than or equal to: [" + maxResultWindow + "] but was [" + resultWindow + "]. See the scroll api for a more efficient way to request large data sets. " + "This limit can be set by changing the [" + IndexSettings.MAX_RESULT_WINDOW_SETTING.getKey() + "] index level setting.");
}
throw new QueryPhaseExecutionException(this, "Batch size is too large, size must be less than or equal to: [" + maxResultWindow + "] but was [" + resultWindow + "]. Scroll batch sizes cost as much memory as result windows so they are controlled by the [" + IndexSettings.MAX_RESULT_WINDOW_SETTING.getKey() + "] index level setting.");
}
if (rescore != null) {
int maxWindow = indexService.getIndexSettings().getMaxRescoreWindow();
for (RescoreSearchContext rescoreContext : rescore) {
if (rescoreContext.window() > maxWindow) {
throw new QueryPhaseExecutionException(this, "Rescore window [" + rescoreContext.window() + "] is too large. It must " + "be less than [" + maxWindow + "]. This prevents allocating massive heaps for storing the results to be " + "rescored. This limit can be set by changing the [" + IndexSettings.MAX_RESCORE_WINDOW_SETTING.getKey() + "] index level setting.");
}
}
}
if (sliceBuilder != null) {
int sliceLimit = indexService.getIndexSettings().getMaxSlicesPerScroll();
int numSlices = sliceBuilder.getMax();
if (numSlices > sliceLimit) {
throw new QueryPhaseExecutionException(this, "The number of slices [" + numSlices + "] is too large. It must " + "be less than [" + sliceLimit + "]. This limit can be set by changing the [" + IndexSettings.MAX_SLICES_PER_SCROLL.getKey() + "] index level setting.");
}
}
// initialize the filtering alias based on the provided filters
try {
final QueryBuilder queryBuilder = request.filteringAliases();
aliasFilter = queryBuilder == null ? null : queryBuilder.toFilter(queryShardContext);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
if (query() == null) {
parsedQuery(ParsedQuery.parsedMatchAllQuery());
}
if (queryBoost() != AbstractQueryBuilder.DEFAULT_BOOST) {
parsedQuery(new ParsedQuery(new FunctionScoreQuery(query(), new WeightFactorFunction(queryBoost)), parsedQuery()));
}
this.query = buildFilteredQuery(query);
if (rewrite) {
try {
this.query = searcher.rewrite(query);
} catch (IOException e) {
throw new QueryPhaseExecutionException(this, "Failed to rewrite main query", e);
}
}
}
use of org.elasticsearch.common.lucene.search.function.WeightFactorFunction in project elasticsearch by elastic.
the class FunctionScoreTests method testSimpleWeightedFunction.
public void testSimpleWeightedFunction() throws IOException, ExecutionException, InterruptedException {
int numFunctions = randomIntBetween(1, 3);
float[] weights = randomFloats(numFunctions);
double[] scores = randomDoubles(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]);
}
FiltersFunctionScoreQuery filtersFunctionScoreQueryWithWeights = getFiltersFunctionScoreQuery(FiltersFunctionScoreQuery.ScoreMode.MULTIPLY, CombineFunction.REPLACE, weightFunctionStubs);
TopDocs topDocsWithWeights = searcher.search(filtersFunctionScoreQueryWithWeights, 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, filtersFunctionScoreQueryWithWeights).getValue();
assertThat(explainedScore / scoreWithWeight, is(1f));
filtersFunctionScoreQueryWithWeights = getFiltersFunctionScoreQuery(FiltersFunctionScoreQuery.ScoreMode.SUM, CombineFunction.REPLACE, weightFunctionStubs);
topDocsWithWeights = searcher.search(filtersFunctionScoreQueryWithWeights, 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, filtersFunctionScoreQueryWithWeights).getValue();
assertThat(explainedScore / scoreWithWeight, is(1f));
filtersFunctionScoreQueryWithWeights = getFiltersFunctionScoreQuery(FiltersFunctionScoreQuery.ScoreMode.AVG, CombineFunction.REPLACE, weightFunctionStubs);
topDocsWithWeights = searcher.search(filtersFunctionScoreQueryWithWeights, 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, filtersFunctionScoreQueryWithWeights).getValue();
assertThat(explainedScore / scoreWithWeight, is(1f));
filtersFunctionScoreQueryWithWeights = getFiltersFunctionScoreQuery(FiltersFunctionScoreQuery.ScoreMode.MIN, CombineFunction.REPLACE, weightFunctionStubs);
topDocsWithWeights = searcher.search(filtersFunctionScoreQueryWithWeights, 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, filtersFunctionScoreQueryWithWeights).getValue();
assertThat(explainedScore / scoreWithWeight, is(1f));
filtersFunctionScoreQueryWithWeights = getFiltersFunctionScoreQuery(FiltersFunctionScoreQuery.ScoreMode.MAX, CombineFunction.REPLACE, weightFunctionStubs);
topDocsWithWeights = searcher.search(filtersFunctionScoreQueryWithWeights, 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, filtersFunctionScoreQueryWithWeights).getValue();
assertThat(explainedScore / scoreWithWeight, is(1f));
}
use of org.elasticsearch.common.lucene.search.function.WeightFactorFunction in project elasticsearch by elastic.
the class FunctionScoreQueryBuilderTests method testWeight1fStillProducesWeightFunction.
public void testWeight1fStillProducesWeightFunction() throws IOException {
assumeTrue("test runs only when at least a type is registered", getCurrentTypes().length > 0);
String queryString = jsonBuilder().startObject().startObject("function_score").startArray("functions").startObject().startObject("field_value_factor").field("field", INT_FIELD_NAME).endObject().field("weight", 1.0).endObject().endArray().endObject().endObject().string();
QueryBuilder query = parseQuery(queryString);
assertThat(query, instanceOf(FunctionScoreQueryBuilder.class));
FunctionScoreQueryBuilder functionScoreQueryBuilder = (FunctionScoreQueryBuilder) query;
assertThat(functionScoreQueryBuilder.filterFunctionBuilders()[0].getScoreFunction(), instanceOf(FieldValueFactorFunctionBuilder.class));
FieldValueFactorFunctionBuilder fieldValueFactorFunctionBuilder = (FieldValueFactorFunctionBuilder) functionScoreQueryBuilder.filterFunctionBuilders()[0].getScoreFunction();
assertThat(fieldValueFactorFunctionBuilder.fieldName(), equalTo(INT_FIELD_NAME));
assertThat(fieldValueFactorFunctionBuilder.factor(), equalTo(FieldValueFactorFunctionBuilder.DEFAULT_FACTOR));
assertThat(fieldValueFactorFunctionBuilder.modifier(), equalTo(FieldValueFactorFunctionBuilder.DEFAULT_MODIFIER));
assertThat(fieldValueFactorFunctionBuilder.getWeight(), equalTo(1f));
assertThat(fieldValueFactorFunctionBuilder.missing(), nullValue());
Query luceneQuery = query.toQuery(createShardContext());
assertThat(luceneQuery, instanceOf(FunctionScoreQuery.class));
FunctionScoreQuery functionScoreQuery = (FunctionScoreQuery) luceneQuery;
assertThat(functionScoreQuery.getFunction(), instanceOf(WeightFactorFunction.class));
WeightFactorFunction weightFactorFunction = (WeightFactorFunction) functionScoreQuery.getFunction();
assertThat(weightFactorFunction.getWeight(), equalTo(1.0f));
assertThat(weightFactorFunction.getScoreFunction(), instanceOf(FieldValueFactorFunction.class));
}
use of org.elasticsearch.common.lucene.search.function.WeightFactorFunction in project elasticsearch by elastic.
the class FunctionScoreTests method testExplanationAndScoreEqualsEvenIfNoFunctionMatches.
public void testExplanationAndScoreEqualsEvenIfNoFunctionMatches() throws IOException {
IndexSearcher localSearcher = newSearcher(reader);
ScoreMode scoreMode = randomFrom(new ScoreMode[] { ScoreMode.SUM, ScoreMode.AVG, ScoreMode.FIRST, ScoreMode.MIN, ScoreMode.MAX, ScoreMode.MULTIPLY });
CombineFunction combineFunction = randomFrom(new CombineFunction[] { CombineFunction.SUM, CombineFunction.AVG, CombineFunction.MIN, CombineFunction.MAX, CombineFunction.MULTIPLY, CombineFunction.REPLACE });
// check for document that has no macthing function
FiltersFunctionScoreQuery query = new FiltersFunctionScoreQuery(new TermQuery(new Term(FIELD, "out")), scoreMode, new FilterFunction[] { new FilterFunction(new TermQuery(new Term("_uid", "2")), new WeightFactorFunction(10)) }, Float.MAX_VALUE, Float.NEGATIVE_INFINITY, combineFunction);
TopDocs searchResult = localSearcher.search(query, 1);
Explanation explanation = localSearcher.explain(query, searchResult.scoreDocs[0].doc);
assertThat(searchResult.scoreDocs[0].score, equalTo(explanation.getValue()));
// check for document that has a matching function
query = new FiltersFunctionScoreQuery(new TermQuery(new Term(FIELD, "out")), scoreMode, new FilterFunction[] { new FilterFunction(new TermQuery(new Term("_uid", "1")), new WeightFactorFunction(10)) }, Float.MAX_VALUE, Float.NEGATIVE_INFINITY, combineFunction);
searchResult = localSearcher.search(query, 1);
explanation = localSearcher.explain(query, searchResult.scoreDocs[0].doc);
assertThat(searchResult.scoreDocs[0].score, equalTo(explanation.getValue()));
}
use of org.elasticsearch.common.lucene.search.function.WeightFactorFunction in project elasticsearch by elastic.
the class FunctionScoreTests method testWeightOnlyCreatesBoostFunction.
public void testWeightOnlyCreatesBoostFunction() throws IOException {
FunctionScoreQuery filtersFunctionScoreQueryWithWeights = new FunctionScoreQuery(new MatchAllDocsQuery(), new WeightFactorFunction(2), 0.0f, CombineFunction.MULTIPLY, 100);
TopDocs topDocsWithWeights = searcher.search(filtersFunctionScoreQueryWithWeights, 1);
float score = topDocsWithWeights.scoreDocs[0].score;
assertThat(score, equalTo(2.0f));
}
Aggregations