Add span within/containing queries.
Expose new span queries from https://issues.apache.org/jira/browse/LUCENE-6083 Within returns matches from 'little' that are enclosed inside of a match from 'big'. Containing returns matches from 'big' that enclose matches from 'little'.
This commit is contained in:
parent
aa968f6b65
commit
aade6194b7
|
@ -52,6 +52,8 @@ include::queries/range-query.asciidoc[]
|
||||||
|
|
||||||
include::queries/regexp-query.asciidoc[]
|
include::queries/regexp-query.asciidoc[]
|
||||||
|
|
||||||
|
include::queries/span-containing-query.asciidoc[]
|
||||||
|
|
||||||
include::queries/span-first-query.asciidoc[]
|
include::queries/span-first-query.asciidoc[]
|
||||||
|
|
||||||
include::queries/span-multi-term-query.asciidoc[]
|
include::queries/span-multi-term-query.asciidoc[]
|
||||||
|
@ -64,6 +66,8 @@ include::queries/span-or-query.asciidoc[]
|
||||||
|
|
||||||
include::queries/span-term-query.asciidoc[]
|
include::queries/span-term-query.asciidoc[]
|
||||||
|
|
||||||
|
include::queries/span-within-query.asciidoc[]
|
||||||
|
|
||||||
include::queries/term-query.asciidoc[]
|
include::queries/term-query.asciidoc[]
|
||||||
|
|
||||||
include::queries/terms-query.asciidoc[]
|
include::queries/terms-query.asciidoc[]
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
[[query-dsl-span-containing-query]]
|
||||||
|
=== Span Containing Query
|
||||||
|
|
||||||
|
Returns matches which enclose another span query. The span within
|
||||||
|
query maps to Lucene `SpanContainingQuery`. Here is an example:
|
||||||
|
|
||||||
|
[source,js]
|
||||||
|
--------------------------------------------------
|
||||||
|
{
|
||||||
|
"span_containing" : {
|
||||||
|
"little" : {
|
||||||
|
"span_term" : { "field1" : "foo" }
|
||||||
|
},
|
||||||
|
"big" : {
|
||||||
|
"span_near" : {
|
||||||
|
"clauses" : [
|
||||||
|
{ "span_term" : { "field1" : "bar" } },
|
||||||
|
{ "span_term" : { "field1" : "baz" } }
|
||||||
|
],
|
||||||
|
"slop" : 5,
|
||||||
|
"in_order" : true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
--------------------------------------------------
|
||||||
|
|
||||||
|
The `big` and `little` clauses can be any span type query. Matching
|
||||||
|
spans from `big` that contain matches from `little` are returned.
|
|
@ -0,0 +1,29 @@
|
||||||
|
[[query-dsl-span-within-query]]
|
||||||
|
=== Span Within Query
|
||||||
|
|
||||||
|
Returns matches which are enclosed inside another span query. The span within
|
||||||
|
query maps to Lucene `SpanWithinQuery`. Here is an example:
|
||||||
|
|
||||||
|
[source,js]
|
||||||
|
--------------------------------------------------
|
||||||
|
{
|
||||||
|
"span_within" : {
|
||||||
|
"little" : {
|
||||||
|
"span_term" : { "field1" : "foo" }
|
||||||
|
},
|
||||||
|
"big" : {
|
||||||
|
"span_near" : {
|
||||||
|
"clauses" : [
|
||||||
|
{ "span_term" : { "field1" : "bar" } },
|
||||||
|
{ "span_term" : { "field1" : "baz" } }
|
||||||
|
],
|
||||||
|
"slop" : 5,
|
||||||
|
"in_order" : true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
--------------------------------------------------
|
||||||
|
|
||||||
|
The `big` and `little` clauses can be any span type query. Matching
|
||||||
|
spans from `little` that are enclosed within `big` are returned.
|
|
@ -318,6 +318,16 @@ public abstract class QueryBuilders {
|
||||||
return new SpanOrQueryBuilder();
|
return new SpanOrQueryBuilder();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Creates a new {@code span_within} builder. */
|
||||||
|
public static SpanWithinQueryBuilder spanWithinQuery() {
|
||||||
|
return new SpanWithinQueryBuilder();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Creates a new {@code span_containing} builder. */
|
||||||
|
public static SpanContainingQueryBuilder spanContainingQuery() {
|
||||||
|
return new SpanContainingQueryBuilder();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a {@link SpanQueryBuilder} which allows having a sub query
|
* Creates a {@link SpanQueryBuilder} which allows having a sub query
|
||||||
* which implements {@link MultiTermQueryBuilder}. This is useful for
|
* which implements {@link MultiTermQueryBuilder}. This is useful for
|
||||||
|
|
|
@ -0,0 +1,92 @@
|
||||||
|
/*
|
||||||
|
* Licensed to Elasticsearch under one or more contributor
|
||||||
|
* license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright
|
||||||
|
* ownership. Elasticsearch licenses this file to you under
|
||||||
|
* the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.elasticsearch.index.query;
|
||||||
|
|
||||||
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builder for {@link SpanContainingQuery}.
|
||||||
|
*/
|
||||||
|
public class SpanContainingQueryBuilder extends BaseQueryBuilder implements SpanQueryBuilder, BoostableQueryBuilder<SpanContainingQueryBuilder> {
|
||||||
|
|
||||||
|
private SpanQueryBuilder big;
|
||||||
|
private SpanQueryBuilder little;
|
||||||
|
private float boost = -1;
|
||||||
|
private String queryName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the little clause, it must be contained within {@code big} for a match.
|
||||||
|
*/
|
||||||
|
public SpanContainingQueryBuilder little(SpanQueryBuilder clause) {
|
||||||
|
this.little = clause;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the big clause, it must enclose {@code little} for a match.
|
||||||
|
*/
|
||||||
|
public SpanContainingQueryBuilder big(SpanQueryBuilder clause) {
|
||||||
|
this.big = clause;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SpanContainingQueryBuilder boost(float boost) {
|
||||||
|
this.boost = boost;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the query name for the filter that can be used when searching for matched_filters per hit.
|
||||||
|
*/
|
||||||
|
public SpanContainingQueryBuilder queryName(String queryName) {
|
||||||
|
this.queryName = queryName;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doXContent(XContentBuilder builder, Params params) throws IOException {
|
||||||
|
if (big == null) {
|
||||||
|
throw new IllegalArgumentException("Must specify big clause when building a span_containing query");
|
||||||
|
}
|
||||||
|
if (little == null) {
|
||||||
|
throw new IllegalArgumentException("Must specify little clause when building a span_containing query");
|
||||||
|
}
|
||||||
|
builder.startObject(SpanContainingQueryParser.NAME);
|
||||||
|
|
||||||
|
builder.field("big");
|
||||||
|
big.toXContent(builder, params);
|
||||||
|
|
||||||
|
builder.field("little");
|
||||||
|
little.toXContent(builder, params);
|
||||||
|
|
||||||
|
if (boost != -1) {
|
||||||
|
builder.field("boost", boost);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (queryName != null) {
|
||||||
|
builder.field("_name", queryName);
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.endObject();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,100 @@
|
||||||
|
/*
|
||||||
|
* Licensed to Elasticsearch under one or more contributor
|
||||||
|
* license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright
|
||||||
|
* ownership. Elasticsearch licenses this file to you under
|
||||||
|
* the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.elasticsearch.index.query;
|
||||||
|
|
||||||
|
import org.apache.lucene.search.Query;
|
||||||
|
import org.apache.lucene.search.spans.SpanContainingQuery;
|
||||||
|
import org.apache.lucene.search.spans.SpanQuery;
|
||||||
|
import org.elasticsearch.common.Strings;
|
||||||
|
import org.elasticsearch.common.inject.Inject;
|
||||||
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parser for {@link SpanContainingQuery}
|
||||||
|
*/
|
||||||
|
public class SpanContainingQueryParser implements QueryParser {
|
||||||
|
|
||||||
|
public static final String NAME = "span_containing";
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public SpanContainingQueryParser() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] names() {
|
||||||
|
return new String[]{NAME, Strings.toCamelCase(NAME)};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Query parse(QueryParseContext parseContext) throws IOException, QueryParsingException {
|
||||||
|
XContentParser parser = parseContext.parser();
|
||||||
|
|
||||||
|
float boost = 1.0f;
|
||||||
|
String queryName = null;
|
||||||
|
SpanQuery big = null;
|
||||||
|
SpanQuery little = null;
|
||||||
|
|
||||||
|
String currentFieldName = null;
|
||||||
|
XContentParser.Token token;
|
||||||
|
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 ("big".equals(currentFieldName)) {
|
||||||
|
Query query = parseContext.parseInnerQuery();
|
||||||
|
if (!(query instanceof SpanQuery)) {
|
||||||
|
throw new QueryParsingException(parseContext, "span_containing [big] must be of type span query");
|
||||||
|
}
|
||||||
|
big = (SpanQuery) query;
|
||||||
|
} else if ("little".equals(currentFieldName)) {
|
||||||
|
Query query = parseContext.parseInnerQuery();
|
||||||
|
if (!(query instanceof SpanQuery)) {
|
||||||
|
throw new QueryParsingException(parseContext, "span_containing [little] must be of type span query");
|
||||||
|
}
|
||||||
|
little = (SpanQuery) query;
|
||||||
|
} else {
|
||||||
|
throw new QueryParsingException(parseContext, "[span_containing] query does not support [" + currentFieldName + "]");
|
||||||
|
}
|
||||||
|
} else if ("boost".equals(currentFieldName)) {
|
||||||
|
boost = parser.floatValue();
|
||||||
|
} else if ("_name".equals(currentFieldName)) {
|
||||||
|
queryName = parser.text();
|
||||||
|
} else {
|
||||||
|
throw new QueryParsingException(parseContext, "[span_containing] query does not support [" + currentFieldName + "]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (big == null) {
|
||||||
|
throw new QueryParsingException(parseContext, "span_containing must include [big]");
|
||||||
|
}
|
||||||
|
if (little == null) {
|
||||||
|
throw new QueryParsingException(parseContext, "span_containing must include [little]");
|
||||||
|
}
|
||||||
|
|
||||||
|
Query query = new SpanContainingQuery(big, little);
|
||||||
|
query.setBoost(boost);
|
||||||
|
if (queryName != null) {
|
||||||
|
parseContext.addNamedQuery(queryName, query);
|
||||||
|
}
|
||||||
|
return query;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,92 @@
|
||||||
|
/*
|
||||||
|
* Licensed to Elasticsearch under one or more contributor
|
||||||
|
* license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright
|
||||||
|
* ownership. Elasticsearch licenses this file to you under
|
||||||
|
* the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.elasticsearch.index.query;
|
||||||
|
|
||||||
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builder for {@link SpanWithinQuery}.
|
||||||
|
*/
|
||||||
|
public class SpanWithinQueryBuilder extends BaseQueryBuilder implements SpanQueryBuilder, BoostableQueryBuilder<SpanWithinQueryBuilder> {
|
||||||
|
|
||||||
|
private SpanQueryBuilder big;
|
||||||
|
private SpanQueryBuilder little;
|
||||||
|
private float boost = -1;
|
||||||
|
private String queryName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the little clause, it must be contained within {@code big} for a match.
|
||||||
|
*/
|
||||||
|
public SpanWithinQueryBuilder little(SpanQueryBuilder clause) {
|
||||||
|
this.little = clause;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the big clause, it must enclose {@code little} for a match.
|
||||||
|
*/
|
||||||
|
public SpanWithinQueryBuilder big(SpanQueryBuilder clause) {
|
||||||
|
this.big = clause;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SpanWithinQueryBuilder boost(float boost) {
|
||||||
|
this.boost = boost;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the query name for the filter that can be used when searching for matched_filters per hit.
|
||||||
|
*/
|
||||||
|
public SpanWithinQueryBuilder queryName(String queryName) {
|
||||||
|
this.queryName = queryName;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doXContent(XContentBuilder builder, Params params) throws IOException {
|
||||||
|
if (big == null) {
|
||||||
|
throw new IllegalArgumentException("Must specify big clause when building a span_within query");
|
||||||
|
}
|
||||||
|
if (little == null) {
|
||||||
|
throw new IllegalArgumentException("Must specify little clause when building a span_within query");
|
||||||
|
}
|
||||||
|
builder.startObject(SpanWithinQueryParser.NAME);
|
||||||
|
|
||||||
|
builder.field("big");
|
||||||
|
big.toXContent(builder, params);
|
||||||
|
|
||||||
|
builder.field("little");
|
||||||
|
little.toXContent(builder, params);
|
||||||
|
|
||||||
|
if (boost != -1) {
|
||||||
|
builder.field("boost", boost);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (queryName != null) {
|
||||||
|
builder.field("_name", queryName);
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.endObject();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,100 @@
|
||||||
|
/*
|
||||||
|
* Licensed to Elasticsearch under one or more contributor
|
||||||
|
* license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright
|
||||||
|
* ownership. Elasticsearch licenses this file to you under
|
||||||
|
* the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.elasticsearch.index.query;
|
||||||
|
|
||||||
|
import org.apache.lucene.search.Query;
|
||||||
|
import org.apache.lucene.search.spans.SpanQuery;
|
||||||
|
import org.apache.lucene.search.spans.SpanWithinQuery;
|
||||||
|
import org.elasticsearch.common.Strings;
|
||||||
|
import org.elasticsearch.common.inject.Inject;
|
||||||
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parser for {@link SpanWithinQuery}
|
||||||
|
*/
|
||||||
|
public class SpanWithinQueryParser implements QueryParser {
|
||||||
|
|
||||||
|
public static final String NAME = "span_within";
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public SpanWithinQueryParser() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] names() {
|
||||||
|
return new String[]{NAME, Strings.toCamelCase(NAME)};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Query parse(QueryParseContext parseContext) throws IOException, QueryParsingException {
|
||||||
|
XContentParser parser = parseContext.parser();
|
||||||
|
|
||||||
|
float boost = 1.0f;
|
||||||
|
String queryName = null;
|
||||||
|
SpanQuery big = null;
|
||||||
|
SpanQuery little = null;
|
||||||
|
|
||||||
|
String currentFieldName = null;
|
||||||
|
XContentParser.Token token;
|
||||||
|
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 ("big".equals(currentFieldName)) {
|
||||||
|
Query query = parseContext.parseInnerQuery();
|
||||||
|
if (query instanceof SpanQuery == false) {
|
||||||
|
throw new QueryParsingException(parseContext, "span_within [big] must be of type span query");
|
||||||
|
}
|
||||||
|
big = (SpanQuery) query;
|
||||||
|
} else if ("little".equals(currentFieldName)) {
|
||||||
|
Query query = parseContext.parseInnerQuery();
|
||||||
|
if (query instanceof SpanQuery == false) {
|
||||||
|
throw new QueryParsingException(parseContext, "span_within [little] must be of type span query");
|
||||||
|
}
|
||||||
|
little = (SpanQuery) query;
|
||||||
|
} else {
|
||||||
|
throw new QueryParsingException(parseContext, "[span_within] query does not support [" + currentFieldName + "]");
|
||||||
|
}
|
||||||
|
} else if ("boost".equals(currentFieldName)) {
|
||||||
|
boost = parser.floatValue();
|
||||||
|
} else if ("_name".equals(currentFieldName)) {
|
||||||
|
queryName = parser.text();
|
||||||
|
} else {
|
||||||
|
throw new QueryParsingException(parseContext, "[span_within] query does not support [" + currentFieldName + "]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (big == null) {
|
||||||
|
throw new QueryParsingException(parseContext, "span_within must include [big]");
|
||||||
|
}
|
||||||
|
if (little == null) {
|
||||||
|
throw new QueryParsingException(parseContext, "span_within must include [little]");
|
||||||
|
}
|
||||||
|
|
||||||
|
Query query = new SpanWithinQuery(big, little);
|
||||||
|
query.setBoost(boost);
|
||||||
|
if (queryName != null) {
|
||||||
|
parseContext.addNamedQuery(queryName, query);
|
||||||
|
}
|
||||||
|
return query;
|
||||||
|
}
|
||||||
|
}
|
|
@ -89,6 +89,8 @@ public class IndicesQueriesModule extends AbstractModule {
|
||||||
qpBinders.addBinding().to(ConstantScoreQueryParser.class).asEagerSingleton();
|
qpBinders.addBinding().to(ConstantScoreQueryParser.class).asEagerSingleton();
|
||||||
qpBinders.addBinding().to(SpanTermQueryParser.class).asEagerSingleton();
|
qpBinders.addBinding().to(SpanTermQueryParser.class).asEagerSingleton();
|
||||||
qpBinders.addBinding().to(SpanNotQueryParser.class).asEagerSingleton();
|
qpBinders.addBinding().to(SpanNotQueryParser.class).asEagerSingleton();
|
||||||
|
qpBinders.addBinding().to(SpanWithinQueryParser.class).asEagerSingleton();
|
||||||
|
qpBinders.addBinding().to(SpanContainingQueryParser.class).asEagerSingleton();
|
||||||
qpBinders.addBinding().to(FieldMaskingSpanQueryParser.class).asEagerSingleton();
|
qpBinders.addBinding().to(FieldMaskingSpanQueryParser.class).asEagerSingleton();
|
||||||
qpBinders.addBinding().to(SpanFirstQueryParser.class).asEagerSingleton();
|
qpBinders.addBinding().to(SpanFirstQueryParser.class).asEagerSingleton();
|
||||||
qpBinders.addBinding().to(SpanNearQueryParser.class).asEagerSingleton();
|
qpBinders.addBinding().to(SpanNearQueryParser.class).asEagerSingleton();
|
||||||
|
|
|
@ -51,12 +51,14 @@ import org.apache.lucene.search.TermQuery;
|
||||||
import org.apache.lucene.search.TermRangeQuery;
|
import org.apache.lucene.search.TermRangeQuery;
|
||||||
import org.apache.lucene.search.WildcardQuery;
|
import org.apache.lucene.search.WildcardQuery;
|
||||||
import org.apache.lucene.search.spans.FieldMaskingSpanQuery;
|
import org.apache.lucene.search.spans.FieldMaskingSpanQuery;
|
||||||
|
import org.apache.lucene.search.spans.SpanContainingQuery;
|
||||||
import org.apache.lucene.search.spans.SpanFirstQuery;
|
import org.apache.lucene.search.spans.SpanFirstQuery;
|
||||||
import org.apache.lucene.search.spans.SpanMultiTermQueryWrapper;
|
import org.apache.lucene.search.spans.SpanMultiTermQueryWrapper;
|
||||||
import org.apache.lucene.search.spans.SpanNearQuery;
|
import org.apache.lucene.search.spans.SpanNearQuery;
|
||||||
import org.apache.lucene.search.spans.SpanNotQuery;
|
import org.apache.lucene.search.spans.SpanNotQuery;
|
||||||
import org.apache.lucene.search.spans.SpanOrQuery;
|
import org.apache.lucene.search.spans.SpanOrQuery;
|
||||||
import org.apache.lucene.search.spans.SpanTermQuery;
|
import org.apache.lucene.search.spans.SpanTermQuery;
|
||||||
|
import org.apache.lucene.search.spans.SpanWithinQuery;
|
||||||
import org.apache.lucene.spatial.prefix.IntersectsPrefixTreeFilter;
|
import org.apache.lucene.spatial.prefix.IntersectsPrefixTreeFilter;
|
||||||
import org.apache.lucene.util.BytesRef;
|
import org.apache.lucene.util.BytesRef;
|
||||||
import org.apache.lucene.util.BytesRefBuilder;
|
import org.apache.lucene.util.BytesRefBuilder;
|
||||||
|
@ -131,11 +133,13 @@ import static org.elasticsearch.index.query.QueryBuilders.prefixQuery;
|
||||||
import static org.elasticsearch.index.query.QueryBuilders.queryStringQuery;
|
import static org.elasticsearch.index.query.QueryBuilders.queryStringQuery;
|
||||||
import static org.elasticsearch.index.query.QueryBuilders.rangeQuery;
|
import static org.elasticsearch.index.query.QueryBuilders.rangeQuery;
|
||||||
import static org.elasticsearch.index.query.QueryBuilders.regexpQuery;
|
import static org.elasticsearch.index.query.QueryBuilders.regexpQuery;
|
||||||
|
import static org.elasticsearch.index.query.QueryBuilders.spanContainingQuery;
|
||||||
import static org.elasticsearch.index.query.QueryBuilders.spanFirstQuery;
|
import static org.elasticsearch.index.query.QueryBuilders.spanFirstQuery;
|
||||||
import static org.elasticsearch.index.query.QueryBuilders.spanNearQuery;
|
import static org.elasticsearch.index.query.QueryBuilders.spanNearQuery;
|
||||||
import static org.elasticsearch.index.query.QueryBuilders.spanNotQuery;
|
import static org.elasticsearch.index.query.QueryBuilders.spanNotQuery;
|
||||||
import static org.elasticsearch.index.query.QueryBuilders.spanOrQuery;
|
import static org.elasticsearch.index.query.QueryBuilders.spanOrQuery;
|
||||||
import static org.elasticsearch.index.query.QueryBuilders.spanTermQuery;
|
import static org.elasticsearch.index.query.QueryBuilders.spanTermQuery;
|
||||||
|
import static org.elasticsearch.index.query.QueryBuilders.spanWithinQuery;
|
||||||
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
|
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
|
||||||
import static org.elasticsearch.index.query.QueryBuilders.termsQuery;
|
import static org.elasticsearch.index.query.QueryBuilders.termsQuery;
|
||||||
import static org.elasticsearch.index.query.QueryBuilders.wildcardQuery;
|
import static org.elasticsearch.index.query.QueryBuilders.wildcardQuery;
|
||||||
|
@ -1434,6 +1438,50 @@ public class SimpleIndexQueryParserTests extends ElasticsearchSingleNodeTest {
|
||||||
assertThat(((SpanTermQuery) spanNotQuery.getExclude()).getTerm(), equalTo(new Term("age", longToPrefixCoded(35, 0))));
|
assertThat(((SpanTermQuery) spanNotQuery.getExclude()).getTerm(), equalTo(new Term("age", longToPrefixCoded(35, 0))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSpanWithinQueryBuilder() throws IOException {
|
||||||
|
IndexQueryParserService queryParser = queryParser();
|
||||||
|
Query expectedQuery = new SpanWithinQuery(new SpanTermQuery(new Term("age", longToPrefixCoded(34, 0))),
|
||||||
|
new SpanTermQuery(new Term("age", longToPrefixCoded(35, 0))));
|
||||||
|
Query actualQuery = queryParser.parse(spanWithinQuery()
|
||||||
|
.big(spanTermQuery("age", 34))
|
||||||
|
.little(spanTermQuery("age", 35)))
|
||||||
|
.query();
|
||||||
|
assertEquals(expectedQuery, actualQuery);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSpanWithinQueryParser() throws IOException {
|
||||||
|
IndexQueryParserService queryParser = queryParser();
|
||||||
|
Query expectedQuery = new SpanWithinQuery(new SpanTermQuery(new Term("age", longToPrefixCoded(34, 0))),
|
||||||
|
new SpanTermQuery(new Term("age", longToPrefixCoded(35, 0))));
|
||||||
|
String queryText = copyToStringFromClasspath("/org/elasticsearch/index/query/spanWithin.json");
|
||||||
|
Query actualQuery = queryParser.parse(queryText).query();
|
||||||
|
assertEquals(expectedQuery, actualQuery);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSpanContainingQueryBuilder() throws IOException {
|
||||||
|
IndexQueryParserService queryParser = queryParser();
|
||||||
|
Query expectedQuery = new SpanContainingQuery(new SpanTermQuery(new Term("age", longToPrefixCoded(34, 0))),
|
||||||
|
new SpanTermQuery(new Term("age", longToPrefixCoded(35, 0))));
|
||||||
|
Query actualQuery = queryParser.parse(spanContainingQuery()
|
||||||
|
.big(spanTermQuery("age", 34))
|
||||||
|
.little(spanTermQuery("age", 35)))
|
||||||
|
.query();
|
||||||
|
assertEquals(expectedQuery, actualQuery);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSpanContainingQueryParser() throws IOException {
|
||||||
|
IndexQueryParserService queryParser = queryParser();
|
||||||
|
Query expectedQuery = new SpanContainingQuery(new SpanTermQuery(new Term("age", longToPrefixCoded(34, 0))),
|
||||||
|
new SpanTermQuery(new Term("age", longToPrefixCoded(35, 0))));
|
||||||
|
String queryText = copyToStringFromClasspath("/org/elasticsearch/index/query/spanContaining.json");
|
||||||
|
Query actualQuery = queryParser.parse(queryText).query();
|
||||||
|
assertEquals(expectedQuery, actualQuery);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSpanFirstQueryBuilder() throws IOException {
|
public void testSpanFirstQueryBuilder() throws IOException {
|
||||||
IndexQueryParserService queryParser = queryParser();
|
IndexQueryParserService queryParser = queryParser();
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
{
|
||||||
|
span_containing:{
|
||||||
|
big:{
|
||||||
|
span_term:{
|
||||||
|
age:34
|
||||||
|
}
|
||||||
|
},
|
||||||
|
little:{
|
||||||
|
span_term:{
|
||||||
|
age:35
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
{
|
||||||
|
span_within:{
|
||||||
|
big:{
|
||||||
|
span_term:{
|
||||||
|
age:34
|
||||||
|
}
|
||||||
|
},
|
||||||
|
little:{
|
||||||
|
span_term:{
|
||||||
|
age:35
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue