|
@@ -22,24 +22,46 @@ package org.elasticsearch.index.query;
|
|
|
import org.apache.lucene.index.Term;
|
|
|
import org.apache.lucene.search.BoostQuery;
|
|
|
import org.apache.lucene.search.MultiTermQuery;
|
|
|
+import org.apache.lucene.search.PrefixQuery;
|
|
|
import org.apache.lucene.search.Query;
|
|
|
import org.apache.lucene.search.TermQuery;
|
|
|
+import org.apache.lucene.search.spans.FieldMaskingSpanQuery;
|
|
|
import org.apache.lucene.search.spans.SpanBoostQuery;
|
|
|
import org.apache.lucene.search.spans.SpanMultiTermQueryWrapper;
|
|
|
import org.apache.lucene.search.spans.SpanQuery;
|
|
|
+import org.apache.lucene.search.spans.SpanTermQuery;
|
|
|
+import org.elasticsearch.Version;
|
|
|
+import org.elasticsearch.common.Strings;
|
|
|
+import org.elasticsearch.common.compress.CompressedXContent;
|
|
|
import org.elasticsearch.common.io.stream.StreamOutput;
|
|
|
-import org.elasticsearch.common.xcontent.ToXContent;
|
|
|
+import org.elasticsearch.common.settings.Settings;
|
|
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
|
|
+import org.elasticsearch.index.mapper.MapperService;
|
|
|
import org.elasticsearch.search.internal.SearchContext;
|
|
|
import org.elasticsearch.test.AbstractQueryTestCase;
|
|
|
|
|
|
import java.io.IOException;
|
|
|
|
|
|
+import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
|
|
|
import static org.hamcrest.CoreMatchers.containsString;
|
|
|
import static org.hamcrest.CoreMatchers.equalTo;
|
|
|
import static org.hamcrest.CoreMatchers.instanceOf;
|
|
|
+import static org.hamcrest.CoreMatchers.either;
|
|
|
|
|
|
public class SpanMultiTermQueryBuilderTests extends AbstractQueryTestCase<SpanMultiTermQueryBuilder> {
|
|
|
+ @Override
|
|
|
+ protected void initializeAdditionalMappings(MapperService mapperService) throws IOException {
|
|
|
+ XContentBuilder mapping = jsonBuilder().startObject().startObject("_doc").startObject("properties")
|
|
|
+ .startObject("prefix_field")
|
|
|
+ .field("type", "text")
|
|
|
+ .startObject("index_prefixes").endObject()
|
|
|
+ .endObject()
|
|
|
+ .endObject().endObject().endObject();
|
|
|
+
|
|
|
+ mapperService.merge("_doc",
|
|
|
+ new CompressedXContent(Strings.toString(mapping)), MapperService.MergeReason.MAPPING_UPDATE);
|
|
|
+ }
|
|
|
+
|
|
|
@Override
|
|
|
protected SpanMultiTermQueryBuilder doCreateTestQueryBuilder() {
|
|
|
MultiTermQueryBuilder multiTermQueryBuilder = RandomQueryBuilder.createMultiTermQuery(random());
|
|
@@ -62,14 +84,67 @@ public class SpanMultiTermQueryBuilderTests extends AbstractQueryTestCase<SpanMu
|
|
|
BoostQuery boostQuery = (BoostQuery) multiTermQuery;
|
|
|
multiTermQuery = boostQuery.getQuery();
|
|
|
}
|
|
|
- assertThat(multiTermQuery, instanceOf(MultiTermQuery.class));
|
|
|
- assertThat(spanMultiTermQueryWrapper.getWrappedQuery(), equalTo(new SpanMultiTermQueryWrapper<>((MultiTermQuery)multiTermQuery).getWrappedQuery()));
|
|
|
+ assertThat(multiTermQuery, either(instanceOf(MultiTermQuery.class)).or(instanceOf(TermQuery.class)));
|
|
|
+ assertThat(spanMultiTermQueryWrapper.getWrappedQuery(),
|
|
|
+ equalTo(new SpanMultiTermQueryWrapper<>((MultiTermQuery)multiTermQuery).getWrappedQuery()));
|
|
|
}
|
|
|
|
|
|
public void testIllegalArgument() {
|
|
|
expectThrows(IllegalArgumentException.class, () -> new SpanMultiTermQueryBuilder((MultiTermQueryBuilder) null));
|
|
|
}
|
|
|
|
|
|
+ private static class TermMultiTermQueryBuilder implements MultiTermQueryBuilder {
|
|
|
+ @Override
|
|
|
+ public Query toQuery(QueryShardContext context) throws IOException {
|
|
|
+ return new TermQuery(new Term("foo", "bar"));
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Query toFilter(QueryShardContext context) throws IOException {
|
|
|
+ return toQuery(context);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public QueryBuilder queryName(String queryName) {
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public String queryName() {
|
|
|
+ return "foo";
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public float boost() {
|
|
|
+ return 1f;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public QueryBuilder boost(float boost) {
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public String getName() {
|
|
|
+ return "foo";
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public String getWriteableName() {
|
|
|
+ return "foo";
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
|
|
+ return builder;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void writeTo(StreamOutput out) throws IOException {
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* test checks that we throw an {@link UnsupportedOperationException} if the query wrapped
|
|
|
* by {@link SpanMultiTermQueryBuilder} does not generate a lucene {@link MultiTermQuery}.
|
|
@@ -77,69 +152,70 @@ public class SpanMultiTermQueryBuilderTests extends AbstractQueryTestCase<SpanMu
|
|
|
* to a date.
|
|
|
*/
|
|
|
public void testUnsupportedInnerQueryType() throws IOException {
|
|
|
- MultiTermQueryBuilder query = new MultiTermQueryBuilder() {
|
|
|
- @Override
|
|
|
- public Query toQuery(QueryShardContext context) throws IOException {
|
|
|
- return new TermQuery(new Term("foo", "bar"));
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public Query toFilter(QueryShardContext context) throws IOException {
|
|
|
- return toQuery(context);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public QueryBuilder queryName(String queryName) {
|
|
|
- return this;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public String queryName() {
|
|
|
- return "foo";
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public float boost() {
|
|
|
- return 1f;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public QueryBuilder boost(float boost) {
|
|
|
- return this;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public String getName() {
|
|
|
- return "foo";
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public String getWriteableName() {
|
|
|
- return "foo";
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
|
|
- return builder;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void writeTo(StreamOutput out) throws IOException {
|
|
|
-
|
|
|
- }
|
|
|
- };
|
|
|
+ MultiTermQueryBuilder query = new TermMultiTermQueryBuilder();
|
|
|
SpanMultiTermQueryBuilder spamMultiTermQuery = new SpanMultiTermQueryBuilder(query);
|
|
|
UnsupportedOperationException e = expectThrows(UnsupportedOperationException.class,
|
|
|
() -> spamMultiTermQuery.toQuery(createShardContext()));
|
|
|
- assertThat(e.getMessage(), containsString("unsupported inner query, should be " + MultiTermQuery.class.getName()));
|
|
|
+ assertThat(e.getMessage(), containsString("unsupported inner query generated by " + TermMultiTermQueryBuilder.class.getName() +
|
|
|
+ ", should be " + MultiTermQuery.class.getName()));
|
|
|
}
|
|
|
|
|
|
public void testToQueryInnerSpanMultiTerm() throws IOException {
|
|
|
+
|
|
|
Query query = new SpanOrQueryBuilder(createTestQueryBuilder()).toQuery(createShardContext());
|
|
|
//verify that the result is still a span query, despite the boost that might get set (SpanBoostQuery rather than BoostQuery)
|
|
|
assertThat(query, instanceOf(SpanQuery.class));
|
|
|
}
|
|
|
|
|
|
+ public void testToQueryInnerTermQuery() throws IOException {
|
|
|
+ final QueryShardContext context = createShardContext();
|
|
|
+ if (context.getIndexSettings().getIndexVersionCreated().onOrAfter(Version.V_6_4_0)) {
|
|
|
+ Query query = new SpanMultiTermQueryBuilder(new PrefixQueryBuilder("prefix_field", "foo"))
|
|
|
+ .toQuery(context);
|
|
|
+ assertThat(query, instanceOf(FieldMaskingSpanQuery.class));
|
|
|
+ FieldMaskingSpanQuery fieldSpanQuery = (FieldMaskingSpanQuery) query;
|
|
|
+ assertThat(fieldSpanQuery.getField(), equalTo("prefix_field"));
|
|
|
+ assertThat(fieldSpanQuery.getMaskedQuery(), instanceOf(SpanTermQuery.class));
|
|
|
+ SpanTermQuery spanTermQuery = (SpanTermQuery) fieldSpanQuery.getMaskedQuery();
|
|
|
+ assertThat(spanTermQuery.getTerm().text(), equalTo("foo"));
|
|
|
+
|
|
|
+ query = new SpanMultiTermQueryBuilder(new PrefixQueryBuilder("prefix_field", "foo"))
|
|
|
+ .boost(2.0f)
|
|
|
+ .toQuery(context);
|
|
|
+ assertThat(query, instanceOf(SpanBoostQuery.class));
|
|
|
+ SpanBoostQuery boostQuery = (SpanBoostQuery) query;
|
|
|
+ assertThat(boostQuery.getBoost(), equalTo(2.0f));
|
|
|
+ assertThat(boostQuery.getQuery(), instanceOf(FieldMaskingSpanQuery.class));
|
|
|
+ fieldSpanQuery = (FieldMaskingSpanQuery) boostQuery.getQuery();
|
|
|
+ assertThat(fieldSpanQuery.getField(), equalTo("prefix_field"));
|
|
|
+ assertThat(fieldSpanQuery.getMaskedQuery(), instanceOf(SpanTermQuery.class));
|
|
|
+ spanTermQuery = (SpanTermQuery) fieldSpanQuery.getMaskedQuery();
|
|
|
+ assertThat(spanTermQuery.getTerm().text(), equalTo("foo"));
|
|
|
+ } else {
|
|
|
+ Query query = new SpanMultiTermQueryBuilder(new PrefixQueryBuilder("prefix_field", "foo"))
|
|
|
+ .toQuery(context);
|
|
|
+ assertThat(query, instanceOf(SpanMultiTermQueryWrapper.class));
|
|
|
+ SpanMultiTermQueryWrapper wrapper = (SpanMultiTermQueryWrapper) query;
|
|
|
+ assertThat(wrapper.getWrappedQuery(), instanceOf(PrefixQuery.class));
|
|
|
+ PrefixQuery prefixQuery = (PrefixQuery) wrapper.getWrappedQuery();
|
|
|
+ assertThat(prefixQuery.getField(), equalTo("prefix_field"));
|
|
|
+ assertThat(prefixQuery.getPrefix().text(), equalTo("foo"));
|
|
|
+
|
|
|
+ query = new SpanMultiTermQueryBuilder(new PrefixQueryBuilder("prefix_field", "foo"))
|
|
|
+ .boost(2.0f)
|
|
|
+ .toQuery(context);
|
|
|
+ assertThat(query, instanceOf(SpanBoostQuery.class));
|
|
|
+ SpanBoostQuery boostQuery = (SpanBoostQuery) query;
|
|
|
+ assertThat(boostQuery.getBoost(), equalTo(2.0f));
|
|
|
+ assertThat(boostQuery.getQuery(), instanceOf(SpanMultiTermQueryWrapper.class));
|
|
|
+ wrapper = (SpanMultiTermQueryWrapper) boostQuery.getQuery();
|
|
|
+ assertThat(wrapper.getWrappedQuery(), instanceOf(PrefixQuery.class));
|
|
|
+ prefixQuery = (PrefixQuery) wrapper.getWrappedQuery();
|
|
|
+ assertThat(prefixQuery.getField(), equalTo("prefix_field"));
|
|
|
+ assertThat(prefixQuery.getPrefix().text(), equalTo("foo"));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
public void testFromJson() throws IOException {
|
|
|
String json =
|
|
|
"{\n" +
|