Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions docs/changelog/124540.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
pr: 124540
summary: "ES|QL: Fix scoring for full text functions"
area: ES|QL
type: bug
issues: []
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,14 @@ public BoolQuery(Source source, boolean isAnd, List<Query> queries) {
}

@Override
public QueryBuilder asBuilder() {
protected QueryBuilder asBuilder() {
BoolQueryBuilder boolQuery = boolQuery();
for (Query query : queries) {
QueryBuilder queryBuilder = query.toQueryBuilder();
if (isAnd) {
boolQuery.must(query.asBuilder());
boolQuery.must(queryBuilder);
} else {
boolQuery.should(query.asBuilder());
boolQuery.should(queryBuilder);
}
}
return boolQuery;
Expand Down Expand Up @@ -94,4 +95,9 @@ public Query negate(Source source) {
}
return new BoolQuery(source, isAnd == false, negated);
}

@Override
public boolean scorable() {
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public ExistsQuery(Source source, String name) {
}

@Override
public QueryBuilder asBuilder() {
protected QueryBuilder asBuilder() {
return existsQuery(name);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public double distance() {
}

@Override
public QueryBuilder asBuilder() {
protected QueryBuilder asBuilder() {
return QueryBuilders.geoDistanceQuery(field).distance(distance, DistanceUnit.METERS).point(lat, lon);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public MatchAll(Source source) {
}

@Override
public QueryBuilder asBuilder() {
protected QueryBuilder asBuilder() {
return matchAllQuery();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ public Query child() {
}

@Override
public QueryBuilder asBuilder() {
return boolQuery().mustNot(child.asBuilder());
protected QueryBuilder asBuilder() {
return boolQuery().mustNot(child.toQueryBuilder());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public String query() {
}

@Override
public QueryBuilder asBuilder() {
protected QueryBuilder asBuilder() {
return prefixQuery(field, query).caseInsensitive(caseInsensitive);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@
* </p>
*/
public abstract class Query {

// Boosting used to remove scoring from queries that don't contribute to it
public static final float NO_SCORE_BOOST = 0.0f;

private final Source source;

protected Query(Source source) {
Expand All @@ -46,9 +50,20 @@ public Source source() {

/**
* Convert to an Elasticsearch {@link QueryBuilder} all set up to execute
* the query.
* the query. This ensures that queries have appropriate boosting for scoring.
*/
public final QueryBuilder toQueryBuilder() {
QueryBuilder builder = asBuilder();
if (scorable() == false) {
builder = unscore(builder);
}
return builder;
}

/**
* Used internally to convert to retrieve a {@link QueryBuilder} by queries.
*/
public abstract QueryBuilder asBuilder();
protected abstract QueryBuilder asBuilder();

/**
* Used by {@link Query#toString()} to produce a pretty string.
Expand Down Expand Up @@ -85,4 +100,18 @@ public String toString() {
public Query negate(Source source) {
return new NotQuery(source, this);
}

/**
* Defines whether a query should contribute to the overall score
*/
public boolean scorable() {
return false;
}

/**
* Removes score from a query builder, so score is not affected by the query
*/
public static QueryBuilder unscore(QueryBuilder builder) {
return builder.boost(NO_SCORE_BOOST);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public QueryStringQuery(Source source, String query, Map<String, Float> fields,
}

@Override
public QueryBuilder asBuilder() {
protected QueryBuilder asBuilder() {
final QueryStringQueryBuilder queryBuilder = QueryBuilders.queryStringQuery(query);
queryBuilder.fields(fields);
options.forEach((k, v) -> {
Expand Down Expand Up @@ -108,4 +108,9 @@ public boolean equals(Object obj) {
protected String innerToString() {
return fields + ":" + query;
}

@Override
public boolean scorable() {
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public ZoneId zoneId() {
}

@Override
public QueryBuilder asBuilder() {
protected QueryBuilder asBuilder() {
RangeQueryBuilder queryBuilder = rangeQuery(field).from(lower, includeLower).to(upper, includeUpper);
if (Strings.hasText(format)) {
queryBuilder.format(format);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public Boolean caseInsensitive() {
}

@Override
public QueryBuilder asBuilder() {
protected QueryBuilder asBuilder() {
return regexpQuery(field, regex).caseInsensitive(caseInsensitive);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,31 @@

import static org.elasticsearch.index.query.QueryBuilders.termQuery;

/**
* Term query. It can be considered for scoring or not - filters that use term query as implementation will not use scoring,
* but the Term full text function will
*/
public class TermQuery extends Query {

private final String term;
private final Object value;
private final boolean caseInsensitive;
private final boolean scorable;

public TermQuery(Source source, String term, Object value) {
this(source, term, value, false);
}

public TermQuery(Source source, String term, Object value, boolean caseInsensitive) {
this(source, term, value, caseInsensitive, false);
}

public TermQuery(Source source, String term, Object value, boolean caseInsensitive, boolean scorable) {
super(source);
this.term = term;
this.value = value;
this.caseInsensitive = caseInsensitive;
this.scorable = scorable;
}

public String term() {
Expand All @@ -44,15 +54,15 @@ public Boolean caseInsensitive() {
}

@Override
public QueryBuilder asBuilder() {
protected QueryBuilder asBuilder() {
TermQueryBuilder qb = termQuery(term, value);
// ES does not allow case_insensitive to be set to "false", it should be either "true" or not specified
return caseInsensitive == false ? qb : qb.caseInsensitive(caseInsensitive);
}

@Override
public int hashCode() {
return Objects.hash(term, value, caseInsensitive);
return Objects.hash(term, value, caseInsensitive, scorable);
}

@Override
Expand All @@ -68,11 +78,17 @@ public boolean equals(Object obj) {
TermQuery other = (TermQuery) obj;
return Objects.equals(term, other.term)
&& Objects.equals(value, other.value)
&& Objects.equals(caseInsensitive, other.caseInsensitive);
&& Objects.equals(caseInsensitive, other.caseInsensitive)
&& scorable == other.scorable;
}

@Override
protected String innerToString() {
return term + ":" + value;
}

@Override
public boolean scorable() {
return scorable;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public TermsQuery(Source source, String term, Set<Object> values) {
}

@Override
public QueryBuilder asBuilder() {
protected QueryBuilder asBuilder() {
return termsQuery(term, values);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public Boolean caseInsensitive() {
}

@Override
public QueryBuilder asBuilder() {
protected QueryBuilder asBuilder() {
WildcardQueryBuilder wb = wildcardQuery(field, query);
// ES does not allow case_insensitive to be set to "false", it should be either "true" or not specified
return caseInsensitive == false ? wb : wb.caseInsensitive(caseInsensitive);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ private DummyLeafQuery(Source source) {
}

@Override
public QueryBuilder asBuilder() {
protected QueryBuilder asBuilder() {
return null;
}

Expand Down
Loading