This commit is contained in:
parent
0baffda390
commit
b95a4db6e6
|
@ -18,12 +18,14 @@
|
|||
now include entire geohash cell, instead of just geohash center.
|
||||
|
||||
* Attempts to generate multi-term phrase queries against non-text fields
|
||||
with a custom analyzer will now throw an exception
|
||||
with a custom analyzer will now throw an exception.
|
||||
|
||||
* An `envelope` crossing the dateline in a `geo_shape `query is now processed
|
||||
correctly when specified using REST API instead of having its left and
|
||||
right corners flipped.
|
||||
|
||||
* Attempts to set `boost` on inner span queries will now throw a parsing exception.
|
||||
|
||||
[float]
|
||||
==== Adaptive replica selection enabled by default
|
||||
|
||||
|
@ -156,4 +158,4 @@ To deboost a specific query you can use a `boost` comprise between 0 and 1.
|
|||
Negative scores in the Function Score Query are deprecated in 6.x, and are
|
||||
not allowed in this version. If a negative score is produced as a result
|
||||
of computation (e.g. in `script_score` or `field_value_factor` functions),
|
||||
an error will be thrown.
|
||||
an error will be thrown.
|
||||
|
|
|
@ -5,6 +5,12 @@ Span queries are low-level positional queries which provide expert control
|
|||
over the order and proximity of the specified terms. These are typically used
|
||||
to implement very specific queries on legal documents or patents.
|
||||
|
||||
It is only allowed to set boost on an outer span query. Compound span queries,
|
||||
like span_near, only use the list of matching spans of inner span queries in
|
||||
order to find their own spans, which they then use to produce a score. Scores
|
||||
are never computed on inner span queries, which is the reason why boosts are not
|
||||
allowed: they only influence the way scores are computed, not spans.
|
||||
|
||||
Span queries cannot be mixed with non-span queries (with the exception of the `span_multi` query).
|
||||
|
||||
The queries in this group are:
|
||||
|
@ -67,4 +73,4 @@ include::span-containing-query.asciidoc[]
|
|||
|
||||
include::span-within-query.asciidoc[]
|
||||
|
||||
include::span-field-masking-query.asciidoc[]
|
||||
include::span-field-masking-query.asciidoc[]
|
||||
|
|
|
@ -32,6 +32,8 @@ import org.elasticsearch.common.xcontent.XContentParser;
|
|||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
|
||||
import static org.elasticsearch.index.query.SpanQueryBuilder.SpanQueryBuilderUtil.checkNoBoost;
|
||||
|
||||
/**
|
||||
* Builder for {@link org.apache.lucene.search.spans.SpanContainingQuery}.
|
||||
*/
|
||||
|
@ -117,12 +119,14 @@ public class SpanContainingQueryBuilder extends AbstractQueryBuilder<SpanContain
|
|||
throw new ParsingException(parser.getTokenLocation(), "span_containing [big] must be of type span query");
|
||||
}
|
||||
big = (SpanQueryBuilder) query;
|
||||
checkNoBoost(NAME, currentFieldName, parser, big);
|
||||
} else if (LITTLE_FIELD.match(currentFieldName, parser.getDeprecationHandler())) {
|
||||
QueryBuilder query = parseInnerQueryBuilder(parser);
|
||||
if (query instanceof SpanQueryBuilder == false) {
|
||||
throw new ParsingException(parser.getTokenLocation(), "span_containing [little] must be of type span query");
|
||||
}
|
||||
little = (SpanQueryBuilder) query;
|
||||
checkNoBoost(NAME, currentFieldName, parser, little);
|
||||
} else {
|
||||
throw new ParsingException(parser.getTokenLocation(),
|
||||
"[span_containing] query does not support [" + currentFieldName + "]");
|
||||
|
|
|
@ -32,6 +32,8 @@ import org.elasticsearch.common.xcontent.XContentParser;
|
|||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
|
||||
import static org.elasticsearch.index.query.SpanQueryBuilder.SpanQueryBuilderUtil.checkNoBoost;
|
||||
|
||||
public class SpanFirstQueryBuilder extends AbstractQueryBuilder<SpanFirstQueryBuilder> implements SpanQueryBuilder {
|
||||
public static final String NAME = "span_first";
|
||||
|
||||
|
@ -115,9 +117,10 @@ public class SpanFirstQueryBuilder extends AbstractQueryBuilder<SpanFirstQueryBu
|
|||
if (MATCH_FIELD.match(currentFieldName, parser.getDeprecationHandler())) {
|
||||
QueryBuilder query = parseInnerQueryBuilder(parser);
|
||||
if (query instanceof SpanQueryBuilder == false) {
|
||||
throw new ParsingException(parser.getTokenLocation(), "spanFirst [match] must be of type span query");
|
||||
throw new ParsingException(parser.getTokenLocation(), "span_first [match] must be of type span query");
|
||||
}
|
||||
match = (SpanQueryBuilder) query;
|
||||
checkNoBoost(NAME, currentFieldName, parser, match);
|
||||
} else {
|
||||
throw new ParsingException(parser.getTokenLocation(), "[span_first] query does not support [" + currentFieldName + "]");
|
||||
}
|
||||
|
@ -134,10 +137,10 @@ public class SpanFirstQueryBuilder extends AbstractQueryBuilder<SpanFirstQueryBu
|
|||
}
|
||||
}
|
||||
if (match == null) {
|
||||
throw new ParsingException(parser.getTokenLocation(), "spanFirst must have [match] span query clause");
|
||||
throw new ParsingException(parser.getTokenLocation(), "span_first must have [match] span query clause");
|
||||
}
|
||||
if (end == null) {
|
||||
throw new ParsingException(parser.getTokenLocation(), "spanFirst must have [end] set for it");
|
||||
throw new ParsingException(parser.getTokenLocation(), "span_first must have [end] set for it");
|
||||
}
|
||||
SpanFirstQueryBuilder queryBuilder = new SpanFirstQueryBuilder(match, end);
|
||||
queryBuilder.boost(boost).queryName(queryName);
|
||||
|
|
|
@ -38,6 +38,8 @@ import java.util.Collections;
|
|||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import static org.elasticsearch.index.query.SpanQueryBuilder.SpanQueryBuilderUtil.checkNoBoost;
|
||||
|
||||
/**
|
||||
* Matches spans which are near one another. One can specify slop, the maximum number
|
||||
* of intervening unmatched positions, as well as whether matches are required to be in-order.
|
||||
|
@ -166,9 +168,11 @@ public class SpanNearQueryBuilder extends AbstractQueryBuilder<SpanNearQueryBuil
|
|||
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
|
||||
QueryBuilder query = parseInnerQueryBuilder(parser);
|
||||
if (query instanceof SpanQueryBuilder == false) {
|
||||
throw new ParsingException(parser.getTokenLocation(), "spanNear [clauses] must be of type span query");
|
||||
throw new ParsingException(parser.getTokenLocation(), "span_near [clauses] must be of type span query");
|
||||
}
|
||||
clauses.add((SpanQueryBuilder) query);
|
||||
final SpanQueryBuilder clause = (SpanQueryBuilder) query;
|
||||
checkNoBoost(NAME, currentFieldName, parser, clause);
|
||||
clauses.add(clause);
|
||||
}
|
||||
} else {
|
||||
throw new ParsingException(parser.getTokenLocation(), "[span_near] query does not support [" + currentFieldName + "]");
|
||||
|
|
|
@ -32,6 +32,8 @@ import org.elasticsearch.common.xcontent.XContentParser;
|
|||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
|
||||
import static org.elasticsearch.index.query.SpanQueryBuilder.SpanQueryBuilderUtil.checkNoBoost;
|
||||
|
||||
public class SpanNotQueryBuilder extends AbstractQueryBuilder<SpanNotQueryBuilder> implements SpanQueryBuilder {
|
||||
public static final String NAME = "span_not";
|
||||
|
||||
|
@ -181,15 +183,17 @@ public class SpanNotQueryBuilder extends AbstractQueryBuilder<SpanNotQueryBuilde
|
|||
if (INCLUDE_FIELD.match(currentFieldName, parser.getDeprecationHandler())) {
|
||||
QueryBuilder query = parseInnerQueryBuilder(parser);
|
||||
if (query instanceof SpanQueryBuilder == false) {
|
||||
throw new ParsingException(parser.getTokenLocation(), "spanNot [include] must be of type span query");
|
||||
throw new ParsingException(parser.getTokenLocation(), "span_not [include] must be of type span query");
|
||||
}
|
||||
include = (SpanQueryBuilder) query;
|
||||
checkNoBoost(NAME, currentFieldName, parser, include);
|
||||
} else if (EXCLUDE_FIELD.match(currentFieldName, parser.getDeprecationHandler())) {
|
||||
QueryBuilder query = parseInnerQueryBuilder(parser);
|
||||
if (query instanceof SpanQueryBuilder == false) {
|
||||
throw new ParsingException(parser.getTokenLocation(), "spanNot [exclude] must be of type span query");
|
||||
throw new ParsingException(parser.getTokenLocation(), "span_not [exclude] must be of type span query");
|
||||
}
|
||||
exclude = (SpanQueryBuilder) query;
|
||||
checkNoBoost(NAME, currentFieldName, parser, exclude);
|
||||
} else {
|
||||
throw new ParsingException(parser.getTokenLocation(), "[span_not] query does not support [" + currentFieldName + "]");
|
||||
}
|
||||
|
@ -210,13 +214,13 @@ public class SpanNotQueryBuilder extends AbstractQueryBuilder<SpanNotQueryBuilde
|
|||
}
|
||||
}
|
||||
if (include == null) {
|
||||
throw new ParsingException(parser.getTokenLocation(), "spanNot must have [include] span query clause");
|
||||
throw new ParsingException(parser.getTokenLocation(), "span_not must have [include] span query clause");
|
||||
}
|
||||
if (exclude == null) {
|
||||
throw new ParsingException(parser.getTokenLocation(), "spanNot must have [exclude] span query clause");
|
||||
throw new ParsingException(parser.getTokenLocation(), "span_not must have [exclude] span query clause");
|
||||
}
|
||||
if (dist != null && (pre != null || post != null)) {
|
||||
throw new ParsingException(parser.getTokenLocation(), "spanNot can either use [dist] or [pre] & [post] (or none)");
|
||||
throw new ParsingException(parser.getTokenLocation(), "span_not can either use [dist] or [pre] & [post] (or none)");
|
||||
}
|
||||
|
||||
SpanNotQueryBuilder spanNotQuery = new SpanNotQueryBuilder(include, exclude);
|
||||
|
|
|
@ -35,6 +35,8 @@ import java.util.Collections;
|
|||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import static org.elasticsearch.index.query.SpanQueryBuilder.SpanQueryBuilderUtil.checkNoBoost;
|
||||
|
||||
/**
|
||||
* Span query that matches the union of its clauses. Maps to {@link SpanOrQuery}.
|
||||
*/
|
||||
|
@ -113,9 +115,11 @@ public class SpanOrQueryBuilder extends AbstractQueryBuilder<SpanOrQueryBuilder>
|
|||
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
|
||||
QueryBuilder query = parseInnerQueryBuilder(parser);
|
||||
if (query instanceof SpanQueryBuilder == false) {
|
||||
throw new ParsingException(parser.getTokenLocation(), "spanOr [clauses] must be of type span query");
|
||||
throw new ParsingException(parser.getTokenLocation(), "span_or [clauses] must be of type span query");
|
||||
}
|
||||
clauses.add((SpanQueryBuilder) query);
|
||||
final SpanQueryBuilder clause = (SpanQueryBuilder) query;
|
||||
checkNoBoost(NAME, currentFieldName, parser, clause);
|
||||
clauses.add(clause);
|
||||
}
|
||||
} else {
|
||||
throw new ParsingException(parser.getTokenLocation(), "[span_or] query does not support [" + currentFieldName + "]");
|
||||
|
@ -132,7 +136,7 @@ public class SpanOrQueryBuilder extends AbstractQueryBuilder<SpanOrQueryBuilder>
|
|||
}
|
||||
|
||||
if (clauses.isEmpty()) {
|
||||
throw new ParsingException(parser.getTokenLocation(), "spanOr must include [clauses]");
|
||||
throw new ParsingException(parser.getTokenLocation(), "span_or must include [clauses]");
|
||||
}
|
||||
|
||||
SpanOrQueryBuilder queryBuilder = new SpanOrQueryBuilder(clauses.get(0));
|
||||
|
|
|
@ -19,9 +19,37 @@
|
|||
|
||||
package org.elasticsearch.index.query;
|
||||
|
||||
import org.elasticsearch.common.ParsingException;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
|
||||
/**
|
||||
* Marker interface for a specific type of {@link QueryBuilder} that allows to build span queries
|
||||
* Marker interface for a specific type of {@link QueryBuilder} that allows to build span queries.
|
||||
*/
|
||||
public interface SpanQueryBuilder extends QueryBuilder {
|
||||
|
||||
class SpanQueryBuilderUtil {
|
||||
private SpanQueryBuilderUtil() {
|
||||
// utility class
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks boost value of a nested span clause is equal to {@link AbstractQueryBuilder#DEFAULT_BOOST}.
|
||||
*
|
||||
* @param queryName a query name
|
||||
* @param fieldName a field name
|
||||
* @param parser a parser
|
||||
* @param clause a span query builder
|
||||
* @throws ParsingException if query boost value isn't equal to {@link AbstractQueryBuilder#DEFAULT_BOOST}
|
||||
*/
|
||||
static void checkNoBoost(String queryName, String fieldName, XContentParser parser, SpanQueryBuilder clause) {
|
||||
try {
|
||||
if (clause.boost() != AbstractQueryBuilder.DEFAULT_BOOST) {
|
||||
throw new ParsingException(parser.getTokenLocation(), queryName + " [" + fieldName + "] " +
|
||||
"as a nested span clause can't have non-default boost value [" + clause.boost() + "]");
|
||||
}
|
||||
} catch (UnsupportedOperationException ignored) {
|
||||
// if boost is unsupported it can't have been set
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,6 +32,8 @@ import org.elasticsearch.common.xcontent.XContentParser;
|
|||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
|
||||
import static org.elasticsearch.index.query.SpanQueryBuilder.SpanQueryBuilderUtil.checkNoBoost;
|
||||
|
||||
/**
|
||||
* Builder for {@link org.apache.lucene.search.spans.SpanWithinQuery}.
|
||||
*/
|
||||
|
@ -122,12 +124,14 @@ public class SpanWithinQueryBuilder extends AbstractQueryBuilder<SpanWithinQuery
|
|||
throw new ParsingException(parser.getTokenLocation(), "span_within [big] must be of type span query");
|
||||
}
|
||||
big = (SpanQueryBuilder) query;
|
||||
checkNoBoost(NAME, currentFieldName, parser, big);
|
||||
} else if (LITTLE_FIELD.match(currentFieldName, parser.getDeprecationHandler())) {
|
||||
QueryBuilder query = parseInnerQueryBuilder(parser);
|
||||
if (query instanceof SpanQueryBuilder == false) {
|
||||
throw new ParsingException(parser.getTokenLocation(), "span_within [little] must be of type span query");
|
||||
}
|
||||
little = (SpanQueryBuilder) query;
|
||||
checkNoBoost(NAME, currentFieldName, parser, little);
|
||||
} else {
|
||||
throw new ParsingException(parser.getTokenLocation(),
|
||||
"[span_within] query does not support [" + currentFieldName + "]");
|
||||
|
|
|
@ -21,11 +21,13 @@ package org.elasticsearch.index.query;
|
|||
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.apache.lucene.search.spans.SpanContainingQuery;
|
||||
import org.elasticsearch.common.ParsingException;
|
||||
import org.elasticsearch.search.internal.SearchContext;
|
||||
import org.elasticsearch.test.AbstractQueryTestCase;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||
|
||||
public class SpanContainingQueryBuilderTests extends AbstractQueryTestCase<SpanContainingQueryBuilder> {
|
||||
|
@ -80,7 +82,7 @@ public class SpanContainingQueryBuilderTests extends AbstractQueryTestCase<SpanC
|
|||
" }\n" +
|
||||
" }\n" +
|
||||
" },\n" +
|
||||
" \"boost\" : 1.0\n" +
|
||||
" \"boost\" : 2.0\n" +
|
||||
" }\n" +
|
||||
"}";
|
||||
|
||||
|
@ -89,5 +91,92 @@ public class SpanContainingQueryBuilderTests extends AbstractQueryTestCase<SpanC
|
|||
|
||||
assertEquals(json, 2, ((SpanNearQueryBuilder) parsed.bigQuery()).clauses().size());
|
||||
assertEquals(json, "foo", ((SpanTermQueryBuilder) parsed.littleQuery()).value());
|
||||
assertEquals(json, 2.0, parsed.boost(), 0.0);
|
||||
}
|
||||
|
||||
public void testFromJsoWithNonDefaultBoostInBigQuery() {
|
||||
String json =
|
||||
"{\n" +
|
||||
" \"span_containing\" : {\n" +
|
||||
" \"big\" : {\n" +
|
||||
" \"span_near\" : {\n" +
|
||||
" \"clauses\" : [ {\n" +
|
||||
" \"span_term\" : {\n" +
|
||||
" \"field1\" : {\n" +
|
||||
" \"value\" : \"bar\",\n" +
|
||||
" \"boost\" : 1.0\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
" }, {\n" +
|
||||
" \"span_term\" : {\n" +
|
||||
" \"field1\" : {\n" +
|
||||
" \"value\" : \"baz\",\n" +
|
||||
" \"boost\" : 1.0\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
" } ],\n" +
|
||||
" \"slop\" : 5,\n" +
|
||||
" \"in_order\" : true,\n" +
|
||||
" \"boost\" : 2.0\n" +
|
||||
" }\n" +
|
||||
" },\n" +
|
||||
" \"little\" : {\n" +
|
||||
" \"span_term\" : {\n" +
|
||||
" \"field1\" : {\n" +
|
||||
" \"value\" : \"foo\",\n" +
|
||||
" \"boost\" : 1.0\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
" },\n" +
|
||||
" \"boost\" : 1.0\n" +
|
||||
" }\n" +
|
||||
"}";
|
||||
|
||||
Exception exception = expectThrows(ParsingException.class, () -> parseQuery(json));
|
||||
assertThat(exception.getMessage(),
|
||||
equalTo("span_containing [big] as a nested span clause can't have non-default boost value [2.0]"));
|
||||
}
|
||||
|
||||
public void testFromJsonWithNonDefaultBoostInLittleQuery() {
|
||||
String json =
|
||||
"{\n" +
|
||||
" \"span_containing\" : {\n" +
|
||||
" \"little\" : {\n" +
|
||||
" \"span_near\" : {\n" +
|
||||
" \"clauses\" : [ {\n" +
|
||||
" \"span_term\" : {\n" +
|
||||
" \"field1\" : {\n" +
|
||||
" \"value\" : \"bar\",\n" +
|
||||
" \"boost\" : 1.0\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
" }, {\n" +
|
||||
" \"span_term\" : {\n" +
|
||||
" \"field1\" : {\n" +
|
||||
" \"value\" : \"baz\",\n" +
|
||||
" \"boost\" : 1.0\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
" } ],\n" +
|
||||
" \"slop\" : 5,\n" +
|
||||
" \"in_order\" : true,\n" +
|
||||
" \"boost\" : 2.0\n" +
|
||||
" }\n" +
|
||||
" },\n" +
|
||||
" \"big\" : {\n" +
|
||||
" \"span_term\" : {\n" +
|
||||
" \"field1\" : {\n" +
|
||||
" \"value\" : \"foo\",\n" +
|
||||
" \"boost\" : 1.0\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
" },\n" +
|
||||
" \"boost\" : 1.0\n" +
|
||||
" }\n" +
|
||||
"}";
|
||||
|
||||
Exception exception = expectThrows(ParsingException.class, () -> parseQuery(json));
|
||||
assertThat(exception.getMessage(),
|
||||
equalTo("span_containing [little] as a nested span clause can't have non-default boost value [2.0]"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ import org.elasticsearch.test.AbstractQueryTestCase;
|
|||
import java.io.IOException;
|
||||
|
||||
import static org.elasticsearch.index.query.QueryBuilders.spanTermQuery;
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||
|
||||
public class SpanFirstQueryBuilderTests extends AbstractQueryTestCase<SpanFirstQueryBuilder> {
|
||||
|
@ -59,7 +60,7 @@ public class SpanFirstQueryBuilderTests extends AbstractQueryTestCase<SpanFirstQ
|
|||
builder.endObject();
|
||||
|
||||
ParsingException e = expectThrows(ParsingException.class, () -> parseQuery(Strings.toString(builder)));
|
||||
assertTrue(e.getMessage().contains("spanFirst must have [end] set"));
|
||||
assertTrue(e.getMessage().contains("span_first must have [end] set"));
|
||||
}
|
||||
{
|
||||
XContentBuilder builder = XContentFactory.jsonBuilder();
|
||||
|
@ -70,7 +71,7 @@ public class SpanFirstQueryBuilderTests extends AbstractQueryTestCase<SpanFirstQ
|
|||
builder.endObject();
|
||||
|
||||
ParsingException e = expectThrows(ParsingException.class, () -> parseQuery(Strings.toString(builder)));
|
||||
assertTrue(e.getMessage().contains("spanFirst must have [match] span query clause"));
|
||||
assertTrue(e.getMessage().contains("span_first must have [match] span query clause"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -97,4 +98,27 @@ public class SpanFirstQueryBuilderTests extends AbstractQueryTestCase<SpanFirstQ
|
|||
assertEquals(json, 3, parsed.end());
|
||||
assertEquals(json, "kimchy", ((SpanTermQueryBuilder) parsed.innerQuery()).value());
|
||||
}
|
||||
|
||||
|
||||
public void testFromJsonWithNonDefaultBoostInMatchQuery() {
|
||||
String json =
|
||||
"{\n" +
|
||||
" \"span_first\" : {\n" +
|
||||
" \"match\" : {\n" +
|
||||
" \"span_term\" : {\n" +
|
||||
" \"user\" : {\n" +
|
||||
" \"value\" : \"kimchy\",\n" +
|
||||
" \"boost\" : 2.0\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
" },\n" +
|
||||
" \"end\" : 3,\n" +
|
||||
" \"boost\" : 1.0\n" +
|
||||
" }\n" +
|
||||
"}";
|
||||
|
||||
Exception exception = expectThrows(ParsingException.class, () -> parseQuery(json));
|
||||
assertThat(exception.getMessage(),
|
||||
equalTo("span_first [match] as a nested span clause can't have non-default boost value [2.0]"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -114,7 +114,7 @@ public class SpanNearQueryBuilderTests extends AbstractQueryTestCase<SpanNearQue
|
|||
" } ],\n" +
|
||||
" \"slop\" : 12,\n" +
|
||||
" \"in_order\" : false,\n" +
|
||||
" \"boost\" : 1.0\n" +
|
||||
" \"boost\" : 2.0\n" +
|
||||
" }\n" +
|
||||
"}";
|
||||
|
||||
|
@ -124,6 +124,7 @@ public class SpanNearQueryBuilderTests extends AbstractQueryTestCase<SpanNearQue
|
|||
assertEquals(json, 3, parsed.clauses().size());
|
||||
assertEquals(json, 12, parsed.slop());
|
||||
assertEquals(json, false, parsed.inOrder());
|
||||
assertEquals(json, 2.0, parsed.boost(), 0.0);
|
||||
}
|
||||
|
||||
public void testParsingSlopDefault() throws IOException {
|
||||
|
@ -187,4 +188,40 @@ public class SpanNearQueryBuilderTests extends AbstractQueryTestCase<SpanNearQue
|
|||
assertThat(e.getMessage(), containsString("[span_near] query does not support [collect_payloads]"));
|
||||
}
|
||||
|
||||
public void testFromJsonWithNonDefaultBoostInInnerQuery() {
|
||||
String json =
|
||||
"{\n" +
|
||||
" \"span_near\" : {\n" +
|
||||
" \"clauses\" : [ {\n" +
|
||||
" \"span_term\" : {\n" +
|
||||
" \"field\" : {\n" +
|
||||
" \"value\" : \"value1\",\n" +
|
||||
" \"boost\" : 2.0\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
" }, {\n" +
|
||||
" \"span_term\" : {\n" +
|
||||
" \"field\" : {\n" +
|
||||
" \"value\" : \"value2\",\n" +
|
||||
" \"boost\" : 1.0\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
" }, {\n" +
|
||||
" \"span_term\" : {\n" +
|
||||
" \"field\" : {\n" +
|
||||
" \"value\" : \"value3\",\n" +
|
||||
" \"boost\" : 1.0\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
" } ],\n" +
|
||||
" \"slop\" : 12,\n" +
|
||||
" \"in_order\" : false,\n" +
|
||||
" \"boost\" : 1.0\n" +
|
||||
" }\n" +
|
||||
"}";
|
||||
|
||||
Exception exception = expectThrows(ParsingException.class, () -> parseQuery(json));
|
||||
assertThat(exception.getMessage(),
|
||||
equalTo("span_near [clauses] as a nested span clause can't have non-default boost value [2.0]"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -132,7 +132,7 @@ public class SpanNotQueryBuilderTests extends AbstractQueryTestCase<SpanNotQuery
|
|||
builder.endObject();
|
||||
|
||||
ParsingException e = expectThrows(ParsingException.class, () -> parseQuery(Strings.toString(builder)));
|
||||
assertThat(e.getDetailedMessage(), containsString("spanNot must have [include]"));
|
||||
assertThat(e.getDetailedMessage(), containsString("span_not must have [include]"));
|
||||
}
|
||||
{
|
||||
XContentBuilder builder = XContentFactory.jsonBuilder();
|
||||
|
@ -146,7 +146,7 @@ public class SpanNotQueryBuilderTests extends AbstractQueryTestCase<SpanNotQuery
|
|||
builder.endObject();
|
||||
|
||||
ParsingException e = expectThrows(ParsingException.class, () -> parseQuery(Strings.toString(builder)));
|
||||
assertThat(e.getDetailedMessage(), containsString("spanNot must have [exclude]"));
|
||||
assertThat(e.getDetailedMessage(), containsString("span_not must have [exclude]"));
|
||||
}
|
||||
{
|
||||
XContentBuilder builder = XContentFactory.jsonBuilder();
|
||||
|
@ -163,7 +163,7 @@ public class SpanNotQueryBuilderTests extends AbstractQueryTestCase<SpanNotQuery
|
|||
builder.endObject();
|
||||
|
||||
ParsingException e = expectThrows(ParsingException.class, () -> parseQuery(Strings.toString(builder)));
|
||||
assertThat(e.getDetailedMessage(), containsString("spanNot can either use [dist] or [pre] & [post] (or none)"));
|
||||
assertThat(e.getDetailedMessage(), containsString("span_not can either use [dist] or [pre] & [post] (or none)"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -203,7 +203,7 @@ public class SpanNotQueryBuilderTests extends AbstractQueryTestCase<SpanNotQuery
|
|||
" },\n" +
|
||||
" \"pre\" : 0,\n" +
|
||||
" \"post\" : 0,\n" +
|
||||
" \"boost\" : 1.0\n" +
|
||||
" \"boost\" : 2.0\n" +
|
||||
" }\n" +
|
||||
"}";
|
||||
|
||||
|
@ -212,5 +212,97 @@ public class SpanNotQueryBuilderTests extends AbstractQueryTestCase<SpanNotQuery
|
|||
|
||||
assertEquals(json, "hoya", ((SpanTermQueryBuilder) parsed.includeQuery()).value());
|
||||
assertEquals(json, 2, ((SpanNearQueryBuilder) parsed.excludeQuery()).clauses().size());
|
||||
assertEquals(json, 2.0, parsed.boost(), 0.0);
|
||||
}
|
||||
|
||||
public void testFromJsonWithNonDefaultBoostInIncludeQuery() {
|
||||
String json =
|
||||
"{\n" +
|
||||
" \"span_not\" : {\n" +
|
||||
" \"exclude\" : {\n" +
|
||||
" \"span_term\" : {\n" +
|
||||
" \"field1\" : {\n" +
|
||||
" \"value\" : \"hoya\",\n" +
|
||||
" \"boost\" : 1.0\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
" },\n" +
|
||||
" \"include\" : {\n" +
|
||||
" \"span_near\" : {\n" +
|
||||
" \"clauses\" : [ {\n" +
|
||||
" \"span_term\" : {\n" +
|
||||
" \"field1\" : {\n" +
|
||||
" \"value\" : \"la\",\n" +
|
||||
" \"boost\" : 1.0\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
" }, {\n" +
|
||||
" \"span_term\" : {\n" +
|
||||
" \"field1\" : {\n" +
|
||||
" \"value\" : \"hoya\",\n" +
|
||||
" \"boost\" : 1.0\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
" } ],\n" +
|
||||
" \"slop\" : 0,\n" +
|
||||
" \"in_order\" : true,\n" +
|
||||
" \"boost\" : 2.0\n" +
|
||||
" }\n" +
|
||||
" },\n" +
|
||||
" \"pre\" : 0,\n" +
|
||||
" \"post\" : 0,\n" +
|
||||
" \"boost\" : 1.0\n" +
|
||||
" }\n" +
|
||||
"}";
|
||||
|
||||
Exception exception = expectThrows(ParsingException.class, () -> parseQuery(json));
|
||||
assertThat(exception.getMessage(),
|
||||
equalTo("span_not [include] as a nested span clause can't have non-default boost value [2.0]"));
|
||||
}
|
||||
|
||||
|
||||
public void testFromJsonWithNonDefaultBoostInExcludeQuery() {
|
||||
String json =
|
||||
"{\n" +
|
||||
" \"span_not\" : {\n" +
|
||||
" \"include\" : {\n" +
|
||||
" \"span_term\" : {\n" +
|
||||
" \"field1\" : {\n" +
|
||||
" \"value\" : \"hoya\",\n" +
|
||||
" \"boost\" : 1.0\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
" },\n" +
|
||||
" \"exclude\" : {\n" +
|
||||
" \"span_near\" : {\n" +
|
||||
" \"clauses\" : [ {\n" +
|
||||
" \"span_term\" : {\n" +
|
||||
" \"field1\" : {\n" +
|
||||
" \"value\" : \"la\",\n" +
|
||||
" \"boost\" : 1.0\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
" }, {\n" +
|
||||
" \"span_term\" : {\n" +
|
||||
" \"field1\" : {\n" +
|
||||
" \"value\" : \"hoya\",\n" +
|
||||
" \"boost\" : 1.0\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
" } ],\n" +
|
||||
" \"slop\" : 0,\n" +
|
||||
" \"in_order\" : true,\n" +
|
||||
" \"boost\" : 2.0\n" +
|
||||
" }\n" +
|
||||
" },\n" +
|
||||
" \"pre\" : 0,\n" +
|
||||
" \"post\" : 0,\n" +
|
||||
" \"boost\" : 1.0\n" +
|
||||
" }\n" +
|
||||
"}";
|
||||
|
||||
Exception exception = expectThrows(ParsingException.class, () -> parseQuery(json));
|
||||
assertThat(exception.getMessage(),
|
||||
equalTo("span_not [exclude] as a nested span clause can't have non-default boost value [2.0]"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ package org.elasticsearch.index.query;
|
|||
import org.apache.lucene.search.Query;
|
||||
import org.apache.lucene.search.spans.SpanOrQuery;
|
||||
import org.apache.lucene.search.spans.SpanQuery;
|
||||
import org.elasticsearch.common.ParsingException;
|
||||
import org.elasticsearch.search.internal.SearchContext;
|
||||
import org.elasticsearch.test.AbstractQueryTestCase;
|
||||
|
||||
|
@ -94,7 +95,7 @@ public class SpanOrQueryBuilderTests extends AbstractQueryTestCase<SpanOrQueryBu
|
|||
" }\n" +
|
||||
" }\n" +
|
||||
" } ],\n" +
|
||||
" \"boost\" : 1.0\n" +
|
||||
" \"boost\" : 2.0\n" +
|
||||
" }\n" +
|
||||
"}";
|
||||
|
||||
|
@ -102,5 +103,27 @@ public class SpanOrQueryBuilderTests extends AbstractQueryTestCase<SpanOrQueryBu
|
|||
checkGeneratedJson(json, parsed);
|
||||
|
||||
assertEquals(json, 3, parsed.clauses().size());
|
||||
assertEquals(json, 2.0, parsed.boost(), 0.0);
|
||||
}
|
||||
|
||||
public void testFromJsonWithNonDefaultBoostInInnerQuery() {
|
||||
String json =
|
||||
"{\n" +
|
||||
" \"span_or\" : {\n" +
|
||||
" \"clauses\" : [ {\n" +
|
||||
" \"span_term\" : {\n" +
|
||||
" \"field\" : {\n" +
|
||||
" \"value\" : \"value1\",\n" +
|
||||
" \"boost\" : 2.0\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
" } ],\n" +
|
||||
" \"boost\" : 1.0\n" +
|
||||
" }\n" +
|
||||
"}";
|
||||
|
||||
Exception exception = expectThrows(ParsingException.class, () -> parseQuery(json));
|
||||
assertThat(exception.getMessage(),
|
||||
equalTo("span_or [clauses] as a nested span clause can't have non-default boost value [2.0]"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -76,19 +76,16 @@ public class SpanTermQueryBuilderTests extends AbstractTermQueryTestCase<SpanTer
|
|||
}
|
||||
|
||||
/**
|
||||
* @param amount the number of clauses that will be returned
|
||||
* @return an array of random {@link SpanTermQueryBuilder} with same field name
|
||||
* @param amount a number of clauses that will be returned
|
||||
* @return the array of random {@link SpanTermQueryBuilder} with same field name
|
||||
*/
|
||||
public SpanTermQueryBuilder[] createSpanTermQueryBuilders(int amount) {
|
||||
SpanTermQueryBuilder[] clauses = new SpanTermQueryBuilder[amount];
|
||||
SpanTermQueryBuilder first = createTestQueryBuilder();
|
||||
SpanTermQueryBuilder first = createTestQueryBuilder(false, true);
|
||||
clauses[0] = first;
|
||||
for (int i = 1; i < amount; i++) {
|
||||
// we need same field name in all clauses, so we only randomize value
|
||||
SpanTermQueryBuilder spanTermQuery = new SpanTermQueryBuilder(first.fieldName(), getRandomValueForFieldName(first.fieldName()));
|
||||
if (randomBoolean()) {
|
||||
spanTermQuery.boost(2.0f / randomIntBetween(1, 20));
|
||||
}
|
||||
if (randomBoolean()) {
|
||||
spanTermQuery.queryName(randomAlphaOfLengthBetween(1, 10));
|
||||
}
|
||||
|
|
|
@ -21,11 +21,13 @@ package org.elasticsearch.index.query;
|
|||
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.apache.lucene.search.spans.SpanWithinQuery;
|
||||
import org.elasticsearch.common.ParsingException;
|
||||
import org.elasticsearch.search.internal.SearchContext;
|
||||
import org.elasticsearch.test.AbstractQueryTestCase;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||
|
||||
public class SpanWithinQueryBuilderTests extends AbstractQueryTestCase<SpanWithinQueryBuilder> {
|
||||
|
@ -80,7 +82,7 @@ public class SpanWithinQueryBuilderTests extends AbstractQueryTestCase<SpanWithi
|
|||
" }\n" +
|
||||
" }\n" +
|
||||
" },\n" +
|
||||
" \"boost\" : 1.0\n" +
|
||||
" \"boost\" : 2.0\n" +
|
||||
" }\n" +
|
||||
"}";
|
||||
|
||||
|
@ -89,5 +91,92 @@ public class SpanWithinQueryBuilderTests extends AbstractQueryTestCase<SpanWithi
|
|||
|
||||
assertEquals(json, "foo", ((SpanTermQueryBuilder) parsed.littleQuery()).value());
|
||||
assertEquals(json, 2, ((SpanNearQueryBuilder) parsed.bigQuery()).clauses().size());
|
||||
assertEquals(json, 2.0, parsed.boost(), 0.0);
|
||||
}
|
||||
|
||||
public void testFromJsonWithNonDefaultBoostInBigQuery() {
|
||||
String json =
|
||||
"{\n" +
|
||||
" \"span_within\" : {\n" +
|
||||
" \"big\" : {\n" +
|
||||
" \"span_near\" : {\n" +
|
||||
" \"clauses\" : [ {\n" +
|
||||
" \"span_term\" : {\n" +
|
||||
" \"field1\" : {\n" +
|
||||
" \"value\" : \"bar\",\n" +
|
||||
" \"boost\" : 1.0\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
" }, {\n" +
|
||||
" \"span_term\" : {\n" +
|
||||
" \"field1\" : {\n" +
|
||||
" \"value\" : \"baz\",\n" +
|
||||
" \"boost\" : 1.0\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
" } ],\n" +
|
||||
" \"slop\" : 5,\n" +
|
||||
" \"in_order\" : true,\n" +
|
||||
" \"boost\" : 2.0\n" +
|
||||
" }\n" +
|
||||
" },\n" +
|
||||
" \"little\" : {\n" +
|
||||
" \"span_term\" : {\n" +
|
||||
" \"field1\" : {\n" +
|
||||
" \"value\" : \"foo\",\n" +
|
||||
" \"boost\" : 1.0\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
" },\n" +
|
||||
" \"boost\" : 1.0\n" +
|
||||
" }\n" +
|
||||
"}";
|
||||
|
||||
Exception exception = expectThrows(ParsingException.class, () -> parseQuery(json));
|
||||
assertThat(exception.getMessage(),
|
||||
equalTo("span_within [big] as a nested span clause can't have non-default boost value [2.0]"));
|
||||
}
|
||||
|
||||
public void testFromJsonWithNonDefaultBoostInLittleQuery() {
|
||||
String json =
|
||||
"{\n" +
|
||||
" \"span_within\" : {\n" +
|
||||
" \"little\" : {\n" +
|
||||
" \"span_near\" : {\n" +
|
||||
" \"clauses\" : [ {\n" +
|
||||
" \"span_term\" : {\n" +
|
||||
" \"field1\" : {\n" +
|
||||
" \"value\" : \"bar\",\n" +
|
||||
" \"boost\" : 1.0\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
" }, {\n" +
|
||||
" \"span_term\" : {\n" +
|
||||
" \"field1\" : {\n" +
|
||||
" \"value\" : \"baz\",\n" +
|
||||
" \"boost\" : 1.0\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
" } ],\n" +
|
||||
" \"slop\" : 5,\n" +
|
||||
" \"in_order\" : true,\n" +
|
||||
" \"boost\" : 2.0\n" +
|
||||
" }\n" +
|
||||
" },\n" +
|
||||
" \"big\" : {\n" +
|
||||
" \"span_term\" : {\n" +
|
||||
" \"field1\" : {\n" +
|
||||
" \"value\" : \"foo\",\n" +
|
||||
" \"boost\" : 1.0\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
" },\n" +
|
||||
" \"boost\" : 1.0\n" +
|
||||
" }\n" +
|
||||
"}";
|
||||
|
||||
Exception exception = expectThrows(ParsingException.class, () -> parseQuery(json));
|
||||
assertThat(exception.getMessage(),
|
||||
equalTo("span_within [little] as a nested span clause can't have non-default boost value [2.0]"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,12 @@ import java.io.UnsupportedEncodingException;
|
|||
public class WrapperQueryBuilderTests extends AbstractQueryTestCase<WrapperQueryBuilder> {
|
||||
|
||||
@Override
|
||||
protected boolean supportsBoostAndQueryName() {
|
||||
protected boolean supportsBoost() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean supportsQueryName() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
package org.elasticsearch.test;
|
||||
|
||||
import com.fasterxml.jackson.core.io.JsonStringEncoder;
|
||||
|
||||
import org.apache.lucene.search.BoostQuery;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.apache.lucene.search.TermQuery;
|
||||
|
@ -83,15 +82,16 @@ public abstract class AbstractQueryTestCase<QB extends AbstractQueryBuilder<QB>>
|
|||
private static final int NUMBER_OF_TESTQUERIES = 20;
|
||||
|
||||
public final QB createTestQueryBuilder() {
|
||||
return createTestQueryBuilder(supportsBoost(), supportsQueryName());
|
||||
}
|
||||
|
||||
public final QB createTestQueryBuilder(boolean supportsBoost, boolean supportsQueryName) {
|
||||
QB query = doCreateTestQueryBuilder();
|
||||
//we should not set boost and query name for queries that don't parse it
|
||||
if (supportsBoostAndQueryName()) {
|
||||
if (randomBoolean()) {
|
||||
query.boost(2.0f / randomIntBetween(1, 20));
|
||||
}
|
||||
if (randomBoolean()) {
|
||||
query.queryName(createUniqueRandomName());
|
||||
}
|
||||
if (supportsBoost && randomBoolean()) {
|
||||
query.boost(2.0f / randomIntBetween(1, 20));
|
||||
}
|
||||
if (supportsQueryName && randomBoolean()) {
|
||||
query.queryName(createUniqueRandomName());
|
||||
}
|
||||
return query;
|
||||
}
|
||||
|
@ -460,7 +460,7 @@ public abstract class AbstractQueryTestCase<QB extends AbstractQueryBuilder<QB>>
|
|||
rewrite(secondLuceneQuery), rewrite(firstLuceneQuery));
|
||||
}
|
||||
|
||||
if (supportsBoostAndQueryName()) {
|
||||
if (supportsBoost()) {
|
||||
secondQuery.boost(firstQuery.boost() + 1f + randomFloat());
|
||||
Query thirdLuceneQuery = rewriteQuery(secondQuery, context).toQuery(context);
|
||||
assertNotEquals("modifying the boost doesn't affect the corresponding lucene query", rewrite(firstLuceneQuery),
|
||||
|
@ -487,12 +487,22 @@ public abstract class AbstractQueryTestCase<QB extends AbstractQueryBuilder<QB>>
|
|||
}
|
||||
|
||||
/**
|
||||
* Few queries allow you to set the boost and queryName on the java api, although the corresponding parser
|
||||
* doesn't parse them as they are not supported. This method allows to disable boost and queryName related tests for those queries.
|
||||
* Those queries are easy to identify: their parsers don't parse `boost` and `_name` as they don't apply to the specific query:
|
||||
* wrapper query and match_none
|
||||
* Few queries allow you to set the boost on the Java API, although the corresponding parser
|
||||
* doesn't parse it as it isn't supported. This method allows to disable boost related tests for those queries.
|
||||
* Those queries are easy to identify: their parsers don't parse {@code boost} as they don't apply to the specific query:
|
||||
* wrapper query and {@code match_none}.
|
||||
*/
|
||||
protected boolean supportsBoostAndQueryName() {
|
||||
protected boolean supportsBoost() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Few queries allow you to set the query name on the Java API, although the corresponding parser
|
||||
* doesn't parse it as it isn't supported. This method allows to disable query name related tests for those queries.
|
||||
* Those queries are easy to identify: their parsers don't parse {@code _name} as they don't apply to the specific query:
|
||||
* wrapper query and {@code match_none}.
|
||||
*/
|
||||
protected boolean supportsQueryName() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue