Search in sources :

Example 1 with CombineFunction

use of org.elasticsearch.common.lucene.search.function.CombineFunction in project elasticsearch by elastic.

the class FunctionScoreQueryBuilder method doToQuery.

@Override
protected Query doToQuery(QueryShardContext context) throws IOException {
    FilterFunction[] filterFunctions = new FilterFunction[filterFunctionBuilders.length];
    int i = 0;
    for (FilterFunctionBuilder filterFunctionBuilder : filterFunctionBuilders) {
        Query filter = filterFunctionBuilder.getFilter().toQuery(context);
        ScoreFunction scoreFunction = filterFunctionBuilder.getScoreFunction().toFunction(context);
        filterFunctions[i++] = new FilterFunction(filter, scoreFunction);
    }
    Query query = this.query.toQuery(context);
    if (query == null) {
        query = new MatchAllDocsQuery();
    }
    // handle cases where only one score function and no filter was provided. In this case we create a FunctionScoreQuery.
    if (filterFunctions.length == 0 || filterFunctions.length == 1 && (this.filterFunctionBuilders[0].getFilter().getName().equals(MatchAllQueryBuilder.NAME))) {
        ScoreFunction function = filterFunctions.length == 0 ? null : filterFunctions[0].function;
        CombineFunction combineFunction = this.boostMode;
        if (combineFunction == null) {
            if (function != null) {
                combineFunction = function.getDefaultScoreCombiner();
            } else {
                combineFunction = DEFAULT_BOOST_MODE;
            }
        }
        return new FunctionScoreQuery(query, function, minScore, combineFunction, maxBoost);
    }
    // in all other cases we create a FiltersFunctionScoreQuery
    CombineFunction boostMode = this.boostMode == null ? DEFAULT_BOOST_MODE : this.boostMode;
    return new FiltersFunctionScoreQuery(query, scoreMode, filterFunctions, maxBoost, minScore, boostMode);
}
Also used : CombineFunction(org.elasticsearch.common.lucene.search.function.CombineFunction) FilterFunction(org.elasticsearch.common.lucene.search.function.FiltersFunctionScoreQuery.FilterFunction) Query(org.apache.lucene.search.Query) FunctionScoreQuery(org.elasticsearch.common.lucene.search.function.FunctionScoreQuery) MatchAllDocsQuery(org.apache.lucene.search.MatchAllDocsQuery) FiltersFunctionScoreQuery(org.elasticsearch.common.lucene.search.function.FiltersFunctionScoreQuery) FiltersFunctionScoreQuery(org.elasticsearch.common.lucene.search.function.FiltersFunctionScoreQuery) FunctionScoreQuery(org.elasticsearch.common.lucene.search.function.FunctionScoreQuery) FiltersFunctionScoreQuery(org.elasticsearch.common.lucene.search.function.FiltersFunctionScoreQuery) MatchAllDocsQuery(org.apache.lucene.search.MatchAllDocsQuery) ScoreFunction(org.elasticsearch.common.lucene.search.function.ScoreFunction)

Example 2 with CombineFunction

use of org.elasticsearch.common.lucene.search.function.CombineFunction in project elasticsearch by elastic.

the class FunctionScoreTests method testFunctionScoreHashCodeAndEquals.

public void testFunctionScoreHashCodeAndEquals() {
    Float minScore = randomBoolean() ? null : 1.0f;
    CombineFunction combineFunction = randomFrom(CombineFunction.values());
    float maxBoost = randomBoolean() ? Float.POSITIVE_INFINITY : randomFloat();
    ScoreFunction function = randomBoolean() ? null : new DummyScoreFunction(combineFunction);
    FunctionScoreQuery q = new FunctionScoreQuery(new TermQuery(new Term("foo", "bar")), function, minScore, combineFunction, maxBoost);
    FunctionScoreQuery q1 = new FunctionScoreQuery(new TermQuery(new Term("foo", "bar")), function, minScore, combineFunction, maxBoost);
    assertEquals(q, q);
    assertEquals(q.hashCode(), q.hashCode());
    assertEquals(q, q1);
    assertEquals(q.hashCode(), q1.hashCode());
    FunctionScoreQuery diffQuery = new FunctionScoreQuery(new TermQuery(new Term("foo", "baz")), function, minScore, combineFunction, maxBoost);
    FunctionScoreQuery diffMinScore = new FunctionScoreQuery(q.getSubQuery(), function, minScore == null ? 1.0f : null, combineFunction, maxBoost);
    ScoreFunction otherFunciton = function == null ? new DummyScoreFunction(combineFunction) : null;
    FunctionScoreQuery diffFunction = new FunctionScoreQuery(q.getSubQuery(), otherFunciton, minScore, combineFunction, maxBoost);
    FunctionScoreQuery diffMaxBoost = new FunctionScoreQuery(new TermQuery(new Term("foo", "bar")), function, minScore, combineFunction, maxBoost == 1.0f ? 0.9f : 1.0f);
    FunctionScoreQuery[] queries = new FunctionScoreQuery[] { diffFunction, diffMinScore, diffQuery, q, diffMaxBoost };
    final int numIters = randomIntBetween(20, 100);
    for (int i = 0; i < numIters; i++) {
        FunctionScoreQuery left = randomFrom(queries);
        FunctionScoreQuery right = randomFrom(queries);
        if (left == right) {
            assertEquals(left, right);
            assertEquals(left.hashCode(), right.hashCode());
        } else {
            assertNotEquals(left + " == " + right, left, right);
        }
    }
}
Also used : CombineFunction(org.elasticsearch.common.lucene.search.function.CombineFunction) TermQuery(org.apache.lucene.search.TermQuery) FiltersFunctionScoreQuery(org.elasticsearch.common.lucene.search.function.FiltersFunctionScoreQuery) FunctionScoreQuery(org.elasticsearch.common.lucene.search.function.FunctionScoreQuery) Term(org.apache.lucene.index.Term) ScoreFunction(org.elasticsearch.common.lucene.search.function.ScoreFunction) LeafScoreFunction(org.elasticsearch.common.lucene.search.function.LeafScoreFunction) RandomScoreFunction(org.elasticsearch.common.lucene.search.function.RandomScoreFunction)

Example 3 with CombineFunction

use of org.elasticsearch.common.lucene.search.function.CombineFunction 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()));
}
Also used : IndexSearcher(org.apache.lucene.search.IndexSearcher) CombineFunction(org.elasticsearch.common.lucene.search.function.CombineFunction) TopDocs(org.apache.lucene.search.TopDocs) ScoreMode(org.elasticsearch.common.lucene.search.function.FiltersFunctionScoreQuery.ScoreMode) TermQuery(org.apache.lucene.search.TermQuery) WeightFactorFunction(org.elasticsearch.common.lucene.search.function.WeightFactorFunction) FilterFunction(org.elasticsearch.common.lucene.search.function.FiltersFunctionScoreQuery.FilterFunction) FiltersFunctionScoreQuery(org.elasticsearch.common.lucene.search.function.FiltersFunctionScoreQuery) Explanation(org.apache.lucene.search.Explanation) Term(org.apache.lucene.index.Term)

Example 4 with CombineFunction

use of org.elasticsearch.common.lucene.search.function.CombineFunction in project elasticsearch by elastic.

the class FunctionScoreIT method testWithEmptyFunctions.

/** make sure min_score works if functions is empty, see https://github.com/elastic/elasticsearch/issues/10253 */
public void testWithEmptyFunctions() throws IOException, ExecutionException, InterruptedException {
    assertAcked(prepareCreate("test"));
    index("test", "testtype", "1", jsonBuilder().startObject().field("text", "test text").endObject());
    refresh();
    SearchResponse termQuery = client().search(searchRequest().source(searchSource().explain(true).query(termQuery("text", "text")))).get();
    assertSearchResponse(termQuery);
    assertThat(termQuery.getHits().getTotalHits(), equalTo(1L));
    float termQueryScore = termQuery.getHits().getAt(0).getScore();
    for (CombineFunction combineFunction : CombineFunction.values()) {
        testMinScoreApplied(combineFunction, termQueryScore);
    }
}
Also used : CombineFunction(org.elasticsearch.common.lucene.search.function.CombineFunction) SearchResponse(org.elasticsearch.action.search.SearchResponse) ElasticsearchAssertions.assertSearchResponse(org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSearchResponse)

Example 5 with CombineFunction

use of org.elasticsearch.common.lucene.search.function.CombineFunction in project elasticsearch by elastic.

the class FunctionScoreQueryBuilder method fromXContent.

public static FunctionScoreQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
    XContentParser parser = parseContext.parser();
    QueryBuilder query = null;
    float boost = AbstractQueryBuilder.DEFAULT_BOOST;
    String queryName = null;
    FiltersFunctionScoreQuery.ScoreMode scoreMode = FunctionScoreQueryBuilder.DEFAULT_SCORE_MODE;
    float maxBoost = FunctionScoreQuery.DEFAULT_MAX_BOOST;
    Float minScore = null;
    String currentFieldName = null;
    XContentParser.Token token;
    CombineFunction combineFunction = null;
    // Either define array of functions and filters or only one function
    boolean functionArrayFound = false;
    boolean singleFunctionFound = false;
    String singleFunctionName = null;
    List<FunctionScoreQueryBuilder.FilterFunctionBuilder> filterFunctionBuilders = new ArrayList<>();
    while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
        if (token == XContentParser.Token.FIELD_NAME) {
            currentFieldName = parser.currentName();
        } else if (token == XContentParser.Token.START_OBJECT) {
            if (QUERY_FIELD.match(currentFieldName)) {
                if (query != null) {
                    throw new ParsingException(parser.getTokenLocation(), "failed to parse [{}] query. [query] is already defined.", NAME);
                }
                query = parseContext.parseInnerQueryBuilder();
            } else {
                if (singleFunctionFound) {
                    throw new ParsingException(parser.getTokenLocation(), "failed to parse [{}] query. already found function [{}], now encountering [{}]. use [functions] " + "array if you want to define several functions.", NAME, singleFunctionName, currentFieldName);
                }
                if (functionArrayFound) {
                    String errorString = "already found [functions] array, now encountering [" + currentFieldName + "].";
                    handleMisplacedFunctionsDeclaration(parser.getTokenLocation(), errorString);
                }
                singleFunctionFound = true;
                singleFunctionName = currentFieldName;
                ScoreFunctionBuilder<?> scoreFunction = parser.namedObject(ScoreFunctionBuilder.class, currentFieldName, parseContext);
                filterFunctionBuilders.add(new FunctionScoreQueryBuilder.FilterFunctionBuilder(scoreFunction));
            }
        } else if (token == XContentParser.Token.START_ARRAY) {
            if (FUNCTIONS_FIELD.match(currentFieldName)) {
                if (singleFunctionFound) {
                    String errorString = "already found [" + singleFunctionName + "], now encountering [functions].";
                    handleMisplacedFunctionsDeclaration(parser.getTokenLocation(), errorString);
                }
                functionArrayFound = true;
                currentFieldName = parseFiltersAndFunctions(parseContext, filterFunctionBuilders);
            } else {
                throw new ParsingException(parser.getTokenLocation(), "failed to parse [{}] query. array [{}] is not supported", NAME, currentFieldName);
            }
        } else if (token.isValue()) {
            if (SCORE_MODE_FIELD.match(currentFieldName)) {
                scoreMode = FiltersFunctionScoreQuery.ScoreMode.fromString(parser.text());
            } else if (BOOST_MODE_FIELD.match(currentFieldName)) {
                combineFunction = CombineFunction.fromString(parser.text());
            } else if (MAX_BOOST_FIELD.match(currentFieldName)) {
                maxBoost = parser.floatValue();
            } else if (AbstractQueryBuilder.BOOST_FIELD.match(currentFieldName)) {
                boost = parser.floatValue();
            } else if (AbstractQueryBuilder.NAME_FIELD.match(currentFieldName)) {
                queryName = parser.text();
            } else if (MIN_SCORE_FIELD.match(currentFieldName)) {
                minScore = parser.floatValue();
            } else {
                if (singleFunctionFound) {
                    throw new ParsingException(parser.getTokenLocation(), "failed to parse [{}] query. already found function [{}], now encountering [{}]. use [functions] array " + "if you want to define several functions.", NAME, singleFunctionName, currentFieldName);
                }
                if (functionArrayFound) {
                    String errorString = "already found [functions] array, now encountering [" + currentFieldName + "].";
                    handleMisplacedFunctionsDeclaration(parser.getTokenLocation(), errorString);
                }
                if (WEIGHT_FIELD.match(currentFieldName)) {
                    filterFunctionBuilders.add(new FunctionScoreQueryBuilder.FilterFunctionBuilder(new WeightBuilder().setWeight(parser.floatValue())));
                    singleFunctionFound = true;
                    singleFunctionName = currentFieldName;
                } else {
                    throw new ParsingException(parser.getTokenLocation(), "failed to parse [{}] query. field [{}] is not supported", NAME, currentFieldName);
                }
            }
        }
    }
    if (query == null) {
        query = new MatchAllQueryBuilder();
    }
    FunctionScoreQueryBuilder functionScoreQueryBuilder = new FunctionScoreQueryBuilder(query, filterFunctionBuilders.toArray(new FunctionScoreQueryBuilder.FilterFunctionBuilder[filterFunctionBuilders.size()]));
    if (combineFunction != null) {
        functionScoreQueryBuilder.boostMode(combineFunction);
    }
    functionScoreQueryBuilder.scoreMode(scoreMode);
    functionScoreQueryBuilder.maxBoost(maxBoost);
    if (minScore != null) {
        functionScoreQueryBuilder.setMinScore(minScore);
    }
    functionScoreQueryBuilder.boost(boost);
    functionScoreQueryBuilder.queryName(queryName);
    return functionScoreQueryBuilder;
}
Also used : ArrayList(java.util.ArrayList) QueryBuilder(org.elasticsearch.index.query.QueryBuilder) AbstractQueryBuilder(org.elasticsearch.index.query.AbstractQueryBuilder) MatchAllQueryBuilder(org.elasticsearch.index.query.MatchAllQueryBuilder) CombineFunction(org.elasticsearch.common.lucene.search.function.CombineFunction) FiltersFunctionScoreQuery(org.elasticsearch.common.lucene.search.function.FiltersFunctionScoreQuery) ParsingException(org.elasticsearch.common.ParsingException) XContentParser(org.elasticsearch.common.xcontent.XContentParser) MatchAllQueryBuilder(org.elasticsearch.index.query.MatchAllQueryBuilder)

Aggregations

CombineFunction (org.elasticsearch.common.lucene.search.function.CombineFunction)6 FiltersFunctionScoreQuery (org.elasticsearch.common.lucene.search.function.FiltersFunctionScoreQuery)5 Term (org.apache.lucene.index.Term)3 TermQuery (org.apache.lucene.search.TermQuery)3 FilterFunction (org.elasticsearch.common.lucene.search.function.FiltersFunctionScoreQuery.FilterFunction)3 ScoreFunction (org.elasticsearch.common.lucene.search.function.ScoreFunction)3 ScoreMode (org.elasticsearch.common.lucene.search.function.FiltersFunctionScoreQuery.ScoreMode)2 FunctionScoreQuery (org.elasticsearch.common.lucene.search.function.FunctionScoreQuery)2 LeafScoreFunction (org.elasticsearch.common.lucene.search.function.LeafScoreFunction)2 RandomScoreFunction (org.elasticsearch.common.lucene.search.function.RandomScoreFunction)2 ArrayList (java.util.ArrayList)1 Explanation (org.apache.lucene.search.Explanation)1 IndexSearcher (org.apache.lucene.search.IndexSearcher)1 MatchAllDocsQuery (org.apache.lucene.search.MatchAllDocsQuery)1 Query (org.apache.lucene.search.Query)1 TopDocs (org.apache.lucene.search.TopDocs)1 SearchResponse (org.elasticsearch.action.search.SearchResponse)1 ParsingException (org.elasticsearch.common.ParsingException)1 WeightFactorFunction (org.elasticsearch.common.lucene.search.function.WeightFactorFunction)1 XContentParser (org.elasticsearch.common.xcontent.XContentParser)1