Deprecate reference to _type in lookup queries (#37016)

Relates to #35190
This commit is contained in:
Mayya Sharipova 2019-01-08 21:46:41 -05:00 committed by Julie Tibshirani
parent 5f2fbedd8c
commit ec32e66088
27 changed files with 521 additions and 129 deletions

View File

@ -875,7 +875,7 @@ public class CrudIT extends ESRestHighLevelClientTestCase {
// test1: create one doc in dest
UpdateByQueryRequest updateByQueryRequest = new UpdateByQueryRequest();
updateByQueryRequest.indices(sourceIndex);
updateByQueryRequest.setQuery(new IdsQueryBuilder().addIds("1").types("_doc"));
updateByQueryRequest.setQuery(new IdsQueryBuilder().addIds("1"));
updateByQueryRequest.setRefresh(true);
BulkByScrollResponse bulkResponse =
execute(updateByQueryRequest, highLevelClient()::updateByQuery, highLevelClient()::updateByQueryAsync);
@ -917,7 +917,7 @@ public class CrudIT extends ESRestHighLevelClientTestCase {
// test update-by-query rethrottling
UpdateByQueryRequest updateByQueryRequest = new UpdateByQueryRequest();
updateByQueryRequest.indices(sourceIndex);
updateByQueryRequest.setQuery(new IdsQueryBuilder().addIds("1").types("_doc"));
updateByQueryRequest.setQuery(new IdsQueryBuilder().addIds("1"));
updateByQueryRequest.setRefresh(true);
// this following settings are supposed to halt reindexing after first document
@ -987,7 +987,7 @@ public class CrudIT extends ESRestHighLevelClientTestCase {
// test1: delete one doc
DeleteByQueryRequest deleteByQueryRequest = new DeleteByQueryRequest();
deleteByQueryRequest.indices(sourceIndex);
deleteByQueryRequest.setQuery(new IdsQueryBuilder().addIds("1").types("_doc"));
deleteByQueryRequest.setQuery(new IdsQueryBuilder().addIds("1"));
deleteByQueryRequest.setRefresh(true);
BulkByScrollResponse bulkResponse =
execute(deleteByQueryRequest, highLevelClient()::deleteByQuery, highLevelClient()::deleteByQueryAsync);
@ -1009,7 +1009,7 @@ public class CrudIT extends ESRestHighLevelClientTestCase {
// test delete-by-query rethrottling
DeleteByQueryRequest deleteByQueryRequest = new DeleteByQueryRequest();
deleteByQueryRequest.indices(sourceIndex);
deleteByQueryRequest.setQuery(new IdsQueryBuilder().addIds("2", "3").types("_doc"));
deleteByQueryRequest.setQuery(new IdsQueryBuilder().addIds("2", "3"));
deleteByQueryRequest.setRefresh(true);
// this following settings are supposed to halt reindexing after first document

View File

@ -207,11 +207,10 @@ public class QueryDSLDocumentationTests extends ESTestCase {
// Using pre-indexed shapes
GeoShapeQueryBuilder qb = geoShapeQuery(
"pin.location", // <1>
"DEU", // <2>
"countries"); // <3>
qb.relation(ShapeRelation.WITHIN) // <4>
.indexedShapeIndex("shapes") // <5>
.indexedShapePath("location"); // <6>
"DEU"); // <2>
qb.relation(ShapeRelation.WITHIN) // <3>
.indexedShapeIndex("shapes") // <4>
.indexedShapePath("location"); // <5>
// end::indexed_geo_shape
}
}
@ -236,9 +235,6 @@ public class QueryDSLDocumentationTests extends ESTestCase {
public void testIds() {
// tag::ids
idsQuery("my_type", "type2")
.addIds("1", "4", "100");
idsQuery() // <1>
.addIds("1", "4", "100");
// end::ids

View File

@ -51,7 +51,6 @@ include-tagged::{query-dsl-test}[indexed_geo_shape]
--------------------------------------------------
<1> field
<2> The ID of the document that containing the pre-indexed shape.
<3> Index type where the pre-indexed shape is.
<4> relation
<5> Name of the index where the pre-indexed shape is. Defaults to 'shapes'.
<6> The field specified as path containing the pre-indexed shape. Defaults to 'shape'.
<3> relation
<4> Name of the index where the pre-indexed shape is. Defaults to 'shapes'.
<5> The field specified as path containing the pre-indexed shape. Defaults to 'shape'.

View File

@ -8,4 +8,3 @@ See {ref}/query-dsl-ids-query.html[Ids Query]
--------------------------------------------------
include-tagged::{query-dsl-test}[ids]
--------------------------------------------------
<1> type is optional

View File

@ -81,7 +81,7 @@ GET /example/_search
==== Pre-Indexed Shape
The Query also supports using a shape which has already been indexed in
another index and/or index type. This is particularly useful for when
another index. This is particularly useful for when
you have a pre-defined list of shapes which are useful to your
application and you want to reference this using a logical name (for
example 'New Zealand') rather than having to provide their coordinates
@ -90,7 +90,6 @@ each time. In this situation it is only necessary to provide:
* `id` - The ID of the document that containing the pre-indexed shape.
* `index` - Name of the index where the pre-indexed shape is. Defaults
to 'shapes'.
* `type` - Index type where the pre-indexed shape is.
* `path` - The field specified as path containing the pre-indexed shape.
Defaults to 'shape'.
* `routing` - The routing of the shape document if required.
@ -130,7 +129,6 @@ GET /example/_search
"location": {
"indexed_shape": {
"index": "shapes",
"type": "_doc",
"id": "deu",
"path": "location"
}

View File

@ -10,13 +10,9 @@ GET /_search
{
"query": {
"ids" : {
"type" : "_doc",
"values" : ["1", "4", "100"]
}
}
}
--------------------------------------------------
// CONSOLE
The `type` is optional and can be omitted, and can also accept an array
of values. If no type is specified, all types defined in the index mapping are tried.

View File

@ -42,12 +42,10 @@ GET /_search
"like" : [
{
"_index" : "imdb",
"_type" : "movies",
"_id" : "1"
},
{
"_index" : "imdb",
"_type" : "movies",
"_id" : "2"
},
"and potentially some more text here as well"
@ -74,7 +72,6 @@ GET /_search
"like" : [
{
"_index" : "marvel",
"_type" : "quotes",
"doc" : {
"name": {
"first": "Ben",
@ -85,7 +82,6 @@ GET /_search
},
{
"_index" : "marvel",
"_type" : "quotes",
"_id" : "2"
}
],

View File

@ -36,9 +36,6 @@ The terms lookup mechanism supports the following options:
`index`::
The index to fetch the term values from.
`type`::
The type to fetch the term values from.
`id`::
The id of the document to fetch the term values from.
@ -93,7 +90,6 @@ GET /tweets/_search
"terms" : {
"user" : {
"index" : "users",
"type" : "_doc",
"id" : "2",
"path" : "followers"
}

View File

@ -537,7 +537,7 @@ public class PercolatorFieldMapperTests extends ESSingleNodeTestCase {
public void testQueryWithRewrite() throws Exception {
addQueryFieldMappings();
client().prepareIndex("remote", "doc", "1").setSource("field", "value").get();
QueryBuilder queryBuilder = termsLookupQuery("field", new TermsLookup("remote", "doc", "1", "field"));
QueryBuilder queryBuilder = termsLookupQuery("field", new TermsLookup("remote", "1", "field"));
ParsedDocument doc = mapperService.documentMapper("doc").parse(new SourceToParse("test", "doc", "1",
BytesReference.bytes(XContentFactory
.jsonBuilder()

View File

@ -48,7 +48,7 @@
search:
rest_total_hits_as_int: true
index: test_index
body: {"query" : {"terms" : {"user" : {"index" : "test_index", "type" : "test_type", "id" : "u1", "path" : "followers"}}}}
body: {"query" : {"terms" : {"user" : {"index" : "test_index", "id" : "u1", "path" : "followers"}}}}
- match: { hits.total: 2 }
- do:
@ -56,4 +56,4 @@
search:
rest_total_hits_as_int: true
index: test_index
body: {"query" : {"terms" : {"user" : {"index" : "test_index", "type" : "test_type", "id" : "u2", "path" : "followers"}}}}
body: {"query" : {"terms" : {"user" : {"index" : "test_index", "id" : "u2", "path" : "followers"}}}}

View File

@ -0,0 +1,59 @@
---
"Terms Query with No.of terms exceeding index.max_terms_count should FAIL":
- skip:
version: " - 6.99.99"
reason: index.max_terms_count setting has been added in 7.0.0
- do:
indices.create:
index: test_index
body:
settings:
number_of_shards: 1
index.max_terms_count: 2
mappings:
test_type:
properties:
user:
type: keyword
followers:
type: keyword
- do:
bulk:
refresh: true
body:
- '{"index": {"_index": "test_index", "_type": "test_type", "_id": "u1"}}'
- '{"user": "u1", "followers": ["u2", "u3"]}'
- '{"index": {"_index": "test_index", "_type": "test_type", "_id": "u2"}}'
- '{"user": "u2", "followers": ["u1", "u3", "u4"]}'
- '{"index": {"_index": "test_index", "_type": "test_type", "_id": "u3"}}'
- '{"user": "u3", "followers": ["u1"]}'
- '{"index": {"_index": "test_index", "_type": "test_type", "_id": "u4"}}'
- '{"user": "u4", "followers": ["u3"]}'
- do:
search:
rest_total_hits_as_int: true
index: test_index
body: {"query" : {"terms" : {"user" : ["u1", "u2"]}}}
- match: { hits.total: 2 }
- do:
catch: bad_request
search:
rest_total_hits_as_int: true
index: test_index
body: {"query" : {"terms" : {"user" : ["u1", "u2", "u3"]}}}
- do:
search:
rest_total_hits_as_int: true
index: test_index
body: {"query" : {"terms" : {"user" : {"index" : "test_index", "type" : "test_type", "id" : "u1", "path" : "followers"}}}}
- match: { hits.total: 2 }
- do:
catch: bad_request
search:
rest_total_hits_as_int: true
index: test_index
body: {"query" : {"terms" : {"user" : {"index" : "test_index", "type" : "test_type", "id" : "u2", "path" : "followers"}}}}

View File

@ -19,6 +19,7 @@
package org.elasticsearch.index.query;
import org.apache.logging.log4j.LogManager;
import org.apache.lucene.document.LatLonShape;
import org.apache.lucene.geo.Line;
import org.apache.lucene.geo.Polygon;
@ -38,6 +39,7 @@ import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.geo.GeoPoint;
@ -48,6 +50,7 @@ import org.elasticsearch.common.geo.builders.ShapeBuilder;
import org.elasticsearch.common.geo.parsers.ShapeParser;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.logging.DeprecationLogger;
import org.elasticsearch.common.xcontent.LoggingDeprecationHandler;
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
import org.elasticsearch.common.xcontent.XContentBuilder;
@ -66,6 +69,10 @@ import java.util.function.Supplier;
*/
public class GeoShapeQueryBuilder extends AbstractQueryBuilder<GeoShapeQueryBuilder> {
public static final String NAME = "geo_shape";
private static final DeprecationLogger deprecationLogger = new DeprecationLogger(
LogManager.getLogger(GeoShapeQueryBuilder.class));
static final String TYPES_DEPRECATION_MESSAGE = "[types removal] Types are deprecated in [geo_shape] queries. " +
"The type should no longer be specified in the [indexed_shape] section.";
public static final String DEFAULT_SHAPE_INDEX_NAME = "shapes";
public static final String DEFAULT_SHAPE_FIELD_NAME = "shape";
@ -119,6 +126,19 @@ public class GeoShapeQueryBuilder extends AbstractQueryBuilder<GeoShapeQueryBuil
this(fieldName, shape, null, null);
}
/**
* Creates a new GeoShapeQueryBuilder whose Query will be against the given
* field name and will use the Shape found with the given ID
*
* @param fieldName
* Name of the field that will be filtered
* @param indexedShapeId
* ID of the indexed Shape that will be used in the Query
*/
public GeoShapeQueryBuilder(String fieldName, String indexedShapeId) {
this(fieldName, (ShapeBuilder) null, indexedShapeId, null);
}
/**
* Creates a new GeoShapeQueryBuilder whose Query will be against the given
* field name and will use the Shape found with the given ID in the given
@ -130,20 +150,19 @@ public class GeoShapeQueryBuilder extends AbstractQueryBuilder<GeoShapeQueryBuil
* ID of the indexed Shape that will be used in the Query
* @param indexedShapeType
* Index type of the indexed Shapes
* @deprecated use {@link #GeoShapeQueryBuilder(String, String)} instead
*/
@Deprecated
public GeoShapeQueryBuilder(String fieldName, String indexedShapeId, String indexedShapeType) {
this(fieldName, (ShapeBuilder) null, indexedShapeId, indexedShapeType);
}
private GeoShapeQueryBuilder(String fieldName, ShapeBuilder shape, String indexedShapeId, String indexedShapeType) {
private GeoShapeQueryBuilder(String fieldName, ShapeBuilder shape, String indexedShapeId, @Nullable String indexedShapeType) {
if (fieldName == null) {
throw new IllegalArgumentException("fieldName is required");
}
if (shape == null && indexedShapeId == null) {
throw new IllegalArgumentException("either shapeBytes or indexedShapeId and indexedShapeType are required");
}
if (indexedShapeId != null && indexedShapeType == null) {
throw new IllegalArgumentException("indexedShapeType is required if indexedShapeId is specified");
throw new IllegalArgumentException("either shape or indexedShapeId is required");
}
this.fieldName = fieldName;
this.shape = shape;
@ -152,7 +171,8 @@ public class GeoShapeQueryBuilder extends AbstractQueryBuilder<GeoShapeQueryBuil
this.supplier = null;
}
private GeoShapeQueryBuilder(String fieldName, Supplier<ShapeBuilder> supplier, String indexedShapeId, String indexedShapeType) {
private GeoShapeQueryBuilder(String fieldName, Supplier<ShapeBuilder> supplier, String indexedShapeId,
@Nullable String indexedShapeType) {
this.fieldName = fieldName;
this.shape = null;
this.supplier = supplier;
@ -238,7 +258,10 @@ public class GeoShapeQueryBuilder extends AbstractQueryBuilder<GeoShapeQueryBuil
/**
* @return the document type of the indexed Shape that will be used in the
* Query
*
* @deprecated Types are in the process of being removed.
*/
@Deprecated
public String indexedShapeType() {
return indexedShapeType;
}
@ -566,8 +589,10 @@ public class GeoShapeQueryBuilder extends AbstractQueryBuilder<GeoShapeQueryBuil
shape.toXContent(builder, params);
} else {
builder.startObject(INDEXED_SHAPE_FIELD.getPreferredName())
.field(SHAPE_ID_FIELD.getPreferredName(), indexedShapeId)
.field(SHAPE_TYPE_FIELD.getPreferredName(), indexedShapeType);
.field(SHAPE_ID_FIELD.getPreferredName(), indexedShapeId);
if (indexedShapeType != null) {
builder.field(SHAPE_TYPE_FIELD.getPreferredName(), indexedShapeType);
}
if (indexedShapeIndex != null) {
builder.field(SHAPE_INDEX_FIELD.getPreferredName(), indexedShapeIndex);
}
@ -677,6 +702,11 @@ public class GeoShapeQueryBuilder extends AbstractQueryBuilder<GeoShapeQueryBuil
}
}
GeoShapeQueryBuilder builder;
if (type != null) {
deprecationLogger.deprecatedAndMaybeLog(
"geo_share_query_with_types", TYPES_DEPRECATION_MESSAGE);
}
if (shape != null) {
builder = new GeoShapeQueryBuilder(fieldName, shape);
} else {
@ -739,7 +769,12 @@ public class GeoShapeQueryBuilder extends AbstractQueryBuilder<GeoShapeQueryBuil
} else if (this.shape == null) {
SetOnce<ShapeBuilder> supplier = new SetOnce<>();
queryRewriteContext.registerAsyncAction((client, listener) -> {
GetRequest getRequest = new GetRequest(indexedShapeIndex, indexedShapeType, indexedShapeId);
GetRequest getRequest;
if (indexedShapeType == null) {
getRequest = new GetRequest(indexedShapeIndex, indexedShapeId);
} else {
getRequest = new GetRequest(indexedShapeIndex, indexedShapeType, indexedShapeId);
}
getRequest.routing(indexedShapeRouting);
fetch(client, getRequest, indexedShapePath, ActionListener.wrap(builder-> {
supplier.set(builder);

View File

@ -19,6 +19,7 @@
package org.elasticsearch.index.query;
import org.apache.logging.log4j.LogManager;
import org.apache.lucene.search.MatchNoDocsQuery;
import org.apache.lucene.search.Query;
import org.elasticsearch.cluster.metadata.MetaData;
@ -27,6 +28,7 @@ import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.logging.DeprecationLogger;
import org.elasticsearch.common.lucene.search.Queries;
import org.elasticsearch.common.xcontent.ObjectParser;
import org.elasticsearch.common.xcontent.XContentBuilder;
@ -51,6 +53,9 @@ import static org.elasticsearch.common.xcontent.ObjectParser.fromList;
*/
public class IdsQueryBuilder extends AbstractQueryBuilder<IdsQueryBuilder> {
public static final String NAME = "ids";
private static final DeprecationLogger deprecationLogger = new DeprecationLogger(
LogManager.getLogger(IdsQueryBuilder.class));
static final String TYPES_DEPRECATION_MESSAGE = "[types removal] Types are deprecated in [ids] queries.";
private static final ParseField TYPE_FIELD = new ParseField("type");
private static final ParseField VALUES_FIELD = new ParseField("values");
@ -83,8 +88,10 @@ public class IdsQueryBuilder extends AbstractQueryBuilder<IdsQueryBuilder> {
/**
* Add types to query
*
* @deprecated Types are in the process of being removed, prefer to filter on a field instead.
*/
// TODO: Remove
@Deprecated
public IdsQueryBuilder types(String... types) {
if (types == null) {
throw new IllegalArgumentException("[" + NAME + "] types cannot be null");
@ -95,7 +102,10 @@ public class IdsQueryBuilder extends AbstractQueryBuilder<IdsQueryBuilder> {
/**
* Returns the types used in this query
*
* @deprecated Types are in the process of being removed, prefer to filter on a field instead.
*/
@Deprecated
public String[] types() {
return this.types;
}
@ -121,7 +131,9 @@ public class IdsQueryBuilder extends AbstractQueryBuilder<IdsQueryBuilder> {
@Override
protected void doXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject(NAME);
if (types.length > 0) {
builder.array(TYPE_FIELD.getPreferredName(), types);
}
builder.startArray(VALUES_FIELD.getPreferredName());
for (String value : ids) {
builder.value(value);
@ -142,7 +154,11 @@ public class IdsQueryBuilder extends AbstractQueryBuilder<IdsQueryBuilder> {
public static IdsQueryBuilder fromXContent(XContentParser parser) {
try {
return PARSER.apply(parser, null);
IdsQueryBuilder builder = PARSER.apply(parser, null);
if (builder.types().length > 0) {
deprecationLogger.deprecatedAndMaybeLog("ids_query_with_types", TYPES_DEPRECATION_MESSAGE);
}
return builder;
} catch (IllegalArgumentException e) {
throw new ParsingException(parser.getTokenLocation(), e.getMessage(), e);
}

View File

@ -19,6 +19,7 @@
package org.elasticsearch.index.query;
import org.apache.logging.log4j.LogManager;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.index.Fields;
import org.apache.lucene.search.BooleanClause;
@ -41,6 +42,7 @@ import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.io.stream.Writeable;
import org.elasticsearch.common.logging.DeprecationLogger;
import org.elasticsearch.common.lucene.search.MoreLikeThisQuery;
import org.elasticsearch.common.lucene.search.XMoreLikeThis;
import org.elasticsearch.common.lucene.uid.Versions;
@ -53,6 +55,7 @@ import org.elasticsearch.index.VersionType;
import org.elasticsearch.index.mapper.IdFieldMapper;
import org.elasticsearch.index.mapper.KeywordFieldMapper.KeywordFieldType;
import org.elasticsearch.index.mapper.MappedFieldType;
import org.elasticsearch.index.mapper.MapperService;
import org.elasticsearch.index.mapper.TextFieldMapper.TextFieldType;
import java.io.IOException;
@ -66,6 +69,7 @@ import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Stream;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
@ -76,6 +80,11 @@ import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
*/
public class MoreLikeThisQueryBuilder extends AbstractQueryBuilder<MoreLikeThisQueryBuilder> {
public static final String NAME = "more_like_this";
private static final DeprecationLogger deprecationLogger = new DeprecationLogger(
LogManager.getLogger(MoreLikeThisQueryBuilder.class));
static final String TYPES_DEPRECATION_MESSAGE = "[types removal] Types are deprecated in [more_like_this] " +
"queries. The type should no longer be specified in the [like] and [unlike] sections.";
public static final int DEFAULT_MAX_QUERY_TERMS = XMoreLikeThis.DEFAULT_MAX_QUERY_TERMS;
public static final int DEFAULT_MIN_TERM_FREQ = XMoreLikeThis.DEFAULT_MIN_TERM_FREQ;
@ -182,9 +191,41 @@ public class MoreLikeThisQueryBuilder extends AbstractQueryBuilder<MoreLikeThisQ
* Constructor for a given item / document request
*
* @param index the index where the document is located
* @param type the type of the document
* @param id and its id
*/
public Item(@Nullable String index, String id) {
if (id == null) {
throw new IllegalArgumentException("Item requires id to be non-null");
}
this.index = index;
this.id = id;
}
/**
* Constructor for an artificial document request, that is not present in the index.
*
* @param index the index to be used for parsing the doc
* @param doc the document specification
*/
public Item(@Nullable String index, XContentBuilder doc) {
if (doc == null) {
throw new IllegalArgumentException("Item requires doc to be non-null");
}
this.index = index;
this.doc = BytesReference.bytes(doc);
this.xContentType = doc.contentType();
}
/**
* Constructor for a given item / document request
*
* @param index the index where the document is located
* @param type the type of the document
* @param id and its id
*
* @deprecated Types are in the process of being removed, use {@link Item(String, String)} instead.
*/
@Deprecated
public Item(@Nullable String index, @Nullable String type, String id) {
if (id == null) {
throw new IllegalArgumentException("Item requires id to be non-null");
@ -200,7 +241,10 @@ public class MoreLikeThisQueryBuilder extends AbstractQueryBuilder<MoreLikeThisQ
* @param index the index to be used for parsing the doc
* @param type the type to be used for parsing the doc
* @param doc the document specification
*
* @deprecated Types are in the process of being removed, use {@link Item(String, XContentBuilder)} instead.
*/
@Deprecated
public Item(@Nullable String index, @Nullable String type, XContentBuilder doc) {
if (doc == null) {
throw new IllegalArgumentException("Item requires doc to be non-null");
@ -257,10 +301,18 @@ public class MoreLikeThisQueryBuilder extends AbstractQueryBuilder<MoreLikeThisQ
return this;
}
/**
* @deprecated Types are in the process of being removed.
*/
@Deprecated
public String type() {
return type;
}
/**
* @deprecated Types are in the process of being removed.
*/
@Deprecated
public Item type(String type) {
this.type = type;
return this;
@ -912,9 +964,18 @@ public class MoreLikeThisQueryBuilder extends AbstractQueryBuilder<MoreLikeThisQ
if (stopWords != null) {
moreLikeThisQueryBuilder.stopWords(stopWords);
}
if (moreLikeThisQueryBuilder.isTypeless() == false) {
deprecationLogger.deprecatedAndMaybeLog("more_like_this_query_with_types", TYPES_DEPRECATION_MESSAGE);
}
return moreLikeThisQueryBuilder;
}
public boolean isTypeless() {
return Stream.concat(Arrays.stream(likeItems), Arrays.stream(unlikeItems))
.allMatch(item -> item.type == null);
}
private static void parseLikeField(XContentParser parser, List<String> texts, List<Item> items) throws IOException {
if (parser.currentToken().isValue()) {
texts.add(parser.text());
@ -1065,12 +1126,7 @@ public class MoreLikeThisQueryBuilder extends AbstractQueryBuilder<MoreLikeThisQ
item.index(context.index().getName());
}
if (item.type() == null) {
if (context.queryTypes().size() > 1) {
throw new QueryShardException(context,
"ambiguous type for item with id: " + item.id() + " and index: " + item.index());
} else {
item.type(context.queryTypes().iterator().next());
}
item.type(MapperService.SINGLE_MAPPING_NAME);
}
// default fields if not present but don't override for artificial docs
if ((item.fields() == null || item.fields().length == 0) && item.doc() == null) {

View File

@ -121,7 +121,10 @@ public final class QueryBuilders {
* Constructs a query that will match only specific ids within types.
*
* @param types The mapping/doc type
*
* @deprecated Types are in the process of being removed, use {@link #idsQuery()} instead.
*/
@Deprecated
public static IdsQueryBuilder idsQuery(String... types) {
return new IdsQueryBuilder().types(types);
}
@ -646,6 +649,14 @@ public final class QueryBuilders {
return new GeoShapeQueryBuilder(name, shape);
}
public static GeoShapeQueryBuilder geoShapeQuery(String name, String indexedShapeId) {
return new GeoShapeQueryBuilder(name, indexedShapeId);
}
/**
* @deprecated Types are in the process of being removed, use {@link #geoShapeQuery(String, String)} instead.
*/
@Deprecated
public static GeoShapeQueryBuilder geoShapeQuery(String name, String indexedShapeId, String indexedShapeType) {
return new GeoShapeQueryBuilder(name, indexedShapeId, indexedShapeType);
}
@ -662,6 +673,16 @@ public final class QueryBuilders {
return builder;
}
public static GeoShapeQueryBuilder geoIntersectionQuery(String name, String indexedShapeId) {
GeoShapeQueryBuilder builder = geoShapeQuery(name, indexedShapeId);
builder.relation(ShapeRelation.INTERSECTS);
return builder;
}
/**
* @deprecated Types are in the process of being removed, use {@link #geoIntersectionQuery(String, String)} instead.
*/
@Deprecated
public static GeoShapeQueryBuilder geoIntersectionQuery(String name, String indexedShapeId, String indexedShapeType) {
GeoShapeQueryBuilder builder = geoShapeQuery(name, indexedShapeId, indexedShapeType);
builder.relation(ShapeRelation.INTERSECTS);
@ -680,6 +701,16 @@ public final class QueryBuilders {
return builder;
}
public static GeoShapeQueryBuilder geoWithinQuery(String name, String indexedShapeId) {
GeoShapeQueryBuilder builder = geoShapeQuery(name, indexedShapeId);
builder.relation(ShapeRelation.WITHIN);
return builder;
}
/**
* @deprecated Types are in the process of being removed, use {@link #geoWithinQuery(String, String)} instead.
*/
@Deprecated
public static GeoShapeQueryBuilder geoWithinQuery(String name, String indexedShapeId, String indexedShapeType) {
GeoShapeQueryBuilder builder = geoShapeQuery(name, indexedShapeId, indexedShapeType);
builder.relation(ShapeRelation.WITHIN);
@ -698,6 +729,16 @@ public final class QueryBuilders {
return builder;
}
public static GeoShapeQueryBuilder geoDisjointQuery(String name, String indexedShapeId) {
GeoShapeQueryBuilder builder = geoShapeQuery(name, indexedShapeId);
builder.relation(ShapeRelation.DISJOINT);
return builder;
}
/**
* @deprecated Types are in the process of being removed, use {@link #geoDisjointQuery(String, String)} instead.
*/
@Deprecated
public static GeoShapeQueryBuilder geoDisjointQuery(String name, String indexedShapeId, String indexedShapeType) {
GeoShapeQueryBuilder builder = geoShapeQuery(name, indexedShapeId, indexedShapeType);
builder.relation(ShapeRelation.DISJOINT);

View File

@ -19,6 +19,7 @@
package org.elasticsearch.index.query;
import org.apache.logging.log4j.LogManager;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.TermInSetQuery;
import org.apache.lucene.util.BytesRef;
@ -34,6 +35,7 @@ import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.io.stream.BytesStreamOutput;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.logging.DeprecationLogger;
import org.elasticsearch.common.lucene.BytesRefs;
import org.elasticsearch.common.lucene.search.Queries;
import org.elasticsearch.common.xcontent.XContentBuilder;
@ -63,6 +65,11 @@ import java.util.stream.IntStream;
public class TermsQueryBuilder extends AbstractQueryBuilder<TermsQueryBuilder> {
public static final String NAME = "terms";
private static final DeprecationLogger deprecationLogger = new DeprecationLogger(
LogManager.getLogger(TermsQueryBuilder.class));
static final String TYPES_DEPRECATION_MESSAGE = "[types removal] Types are deprecated " +
"in [terms] lookup queries.";
private final String fieldName;
private final List<?> values;
private final TermsLookup termsLookup;
@ -211,6 +218,10 @@ public class TermsQueryBuilder extends AbstractQueryBuilder<TermsQueryBuilder> {
return this.termsLookup;
}
public boolean isTypeless() {
return termsLookup == null || termsLookup.type() == null;
}
private static final Set<Class<? extends Number>> INTEGER_TYPES = new HashSet<>(
Arrays.asList(Byte.class, Short.class, Integer.class, Long.class));
private static final Set<Class<?>> STRING_TYPES = new HashSet<>(
@ -391,9 +402,16 @@ public class TermsQueryBuilder extends AbstractQueryBuilder<TermsQueryBuilder> {
throw new ParsingException(parser.getTokenLocation(), "[" + TermsQueryBuilder.NAME + "] query requires a field name, " +
"followed by array of terms or a document lookup specification");
}
return new TermsQueryBuilder(fieldName, values, termsLookup)
TermsQueryBuilder builder = new TermsQueryBuilder(fieldName, values, termsLookup)
.boost(boost)
.queryName(queryName);
if (builder.isTypeless() == false) {
deprecationLogger.deprecatedAndMaybeLog("terms_lookup_with_types", TYPES_DEPRECATION_MESSAGE);
}
return builder;
}
static List<Object> parseValues(XContentParser parser) throws IOException {
@ -442,8 +460,10 @@ public class TermsQueryBuilder extends AbstractQueryBuilder<TermsQueryBuilder> {
}
private void fetch(TermsLookup termsLookup, Client client, ActionListener<List<Object>> actionListener) {
GetRequest getRequest = new GetRequest(termsLookup.index(), termsLookup.type(), termsLookup.id())
.preference("_local").routing(termsLookup.routing());
GetRequest getRequest = termsLookup.type() == null
? new GetRequest(termsLookup.index(), termsLookup.id())
: new GetRequest(termsLookup.index(), termsLookup.type(), termsLookup.id());
getRequest.preference("_local").routing(termsLookup.routing());
client.get(getRequest, new ActionListener<GetResponse>() {
@Override
public void onResponse(GetResponse getResponse) {

View File

@ -20,11 +20,11 @@
package org.elasticsearch.indices;
import org.elasticsearch.Version;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.io.stream.Writeable;
import org.elasticsearch.common.xcontent.ToXContent.Params;
import org.elasticsearch.common.xcontent.ToXContentFragment;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
@ -38,18 +38,24 @@ import java.util.Objects;
*/
public class TermsLookup implements Writeable, ToXContentFragment {
private final String index;
private final String type;
private @Nullable String type;
private final String id;
private final String path;
private String routing;
public TermsLookup(String index, String id, String path) {
this(index, null, id, path);
}
/**
* @deprecated Types are in the process of being removed, use {@link TermsLookup(String, String, String)} instead.
*/
@Deprecated
public TermsLookup(String index, String type, String id, String path) {
if (id == null) {
throw new IllegalArgumentException("[" + TermsQueryBuilder.NAME + "] query lookup element requires specifying the id.");
}
if (type == null) {
throw new IllegalArgumentException("[" + TermsQueryBuilder.NAME + "] query lookup element requires specifying the type.");
}
if (path == null) {
throw new IllegalArgumentException("[" + TermsQueryBuilder.NAME + "] query lookup element requires specifying the path.");
}
@ -66,7 +72,12 @@ public class TermsLookup implements Writeable, ToXContentFragment {
* Read from a stream.
*/
public TermsLookup(StreamInput in) throws IOException {
if (in.getVersion().onOrAfter(Version.V_7_0_0)) {
type = in.readOptionalString();
} else {
// Before 7.0, the type parameter was always non-null and serialized as a (non-optional) string.
type = in.readString();
}
id = in.readString();
path = in.readString();
if (in.getVersion().onOrAfter(Version.V_6_0_0_beta1)) {
@ -82,7 +93,16 @@ public class TermsLookup implements Writeable, ToXContentFragment {
@Override
public void writeTo(StreamOutput out) throws IOException {
if (out.getVersion().onOrAfter(Version.V_7_0_0)) {
out.writeOptionalString(type);
} else {
if (type == null) {
throw new IllegalArgumentException("Typeless [terms] lookup queries are not supported if any " +
"node is running a version before 7.0.");
}
out.writeString(type);
}
out.writeString(id);
out.writeString(path);
if (out.getVersion().onOrAfter(Version.V_6_0_0_beta1)) {
@ -97,6 +117,10 @@ public class TermsLookup implements Writeable, ToXContentFragment {
return index;
}
/**
* @deprecated Types are in the process of being removed.
*/
@Deprecated
public String type() {
return type;
}
@ -155,18 +179,28 @@ public class TermsLookup implements Writeable, ToXContentFragment {
+ token + "] after [" + currentFieldName + "]");
}
}
if (type == null) {
return new TermsLookup(index, id, path).routing(routing);
} else {
return new TermsLookup(index, type, id, path).routing(routing);
}
}
@Override
public String toString() {
if (type == null) {
return index + "/" + id + "/" + path;
} else {
return index + "/" + type + "/" + id + "/" + path;
}
}
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.field("index", index);
if (type != null) {
builder.field("type", type);
}
builder.field("id", id);
builder.field("path", path);
if (routing != null) {

View File

@ -36,8 +36,10 @@ import org.elasticsearch.common.io.stream.BytesStreamOutput;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.json.JsonXContent;
import org.elasticsearch.index.get.GetResult;
import org.elasticsearch.index.mapper.MapperService;
import org.elasticsearch.search.internal.SearchContext;
import org.elasticsearch.test.AbstractQueryTestCase;
import org.elasticsearch.test.VersionUtils;
@ -94,7 +96,7 @@ public class GeoShapeQueryBuilderTests extends AbstractQueryTestCase<GeoShapeQue
} else {
indexedShapeToReturn = shape;
indexedShapeId = randomAlphaOfLengthBetween(3, 20);
indexedShapeType = randomAlphaOfLengthBetween(3, 20);
indexedShapeType = randomBoolean() ? randomAlphaOfLengthBetween(3, 20) : null;
builder = new GeoShapeQueryBuilder(fieldName(), indexedShapeId, indexedShapeType);
if (randomBoolean()) {
indexedShapeIndex = randomAlphaOfLengthBetween(3, 20);
@ -126,15 +128,17 @@ public class GeoShapeQueryBuilderTests extends AbstractQueryTestCase<GeoShapeQue
@Override
protected GetResponse executeGet(GetRequest getRequest) {
String indexedType = indexedShapeType != null ? indexedShapeType : MapperService.SINGLE_MAPPING_NAME;
assertThat(indexedShapeToReturn, notNullValue());
assertThat(indexedShapeId, notNullValue());
assertThat(indexedShapeType, notNullValue());
assertThat(getRequest.id(), equalTo(indexedShapeId));
assertThat(getRequest.type(), equalTo(indexedShapeType));
assertThat(getRequest.type(), equalTo(indexedType));
assertThat(getRequest.routing(), equalTo(indexedShapeRouting));
String expectedShapeIndex = indexedShapeIndex == null ? GeoShapeQueryBuilder.DEFAULT_SHAPE_INDEX_NAME : indexedShapeIndex;
assertThat(getRequest.index(), equalTo(expectedShapeIndex));
String expectedShapePath = indexedShapePath == null ? GeoShapeQueryBuilder.DEFAULT_SHAPE_FIELD_NAME : indexedShapePath;
String json;
try {
XContentBuilder builder = XContentFactory.jsonBuilder().prettyPrint();
@ -146,7 +150,7 @@ public class GeoShapeQueryBuilderTests extends AbstractQueryTestCase<GeoShapeQue
} catch (IOException ex) {
throw new ElasticsearchException("boom", ex);
}
return new GetResponse(new GetResult(indexedShapeIndex, indexedShapeType, indexedShapeId, 0, 1, 0, true, new BytesArray(json),
return new GetResponse(new GetResult(indexedShapeIndex, indexedType, indexedShapeId, 0, 1, 0, true, new BytesArray(json),
null));
}
@ -176,19 +180,13 @@ public class GeoShapeQueryBuilderTests extends AbstractQueryTestCase<GeoShapeQue
}
public void testNoShape() throws IOException {
expectThrows(IllegalArgumentException.class, () -> new GeoShapeQueryBuilder(fieldName(), null));
expectThrows(IllegalArgumentException.class, () -> new GeoShapeQueryBuilder(fieldName(), (ShapeBuilder) null));
}
public void testNoIndexedShape() throws IOException {
IllegalArgumentException e = expectThrows(IllegalArgumentException.class,
() -> new GeoShapeQueryBuilder(fieldName(), null, "type"));
assertEquals("either shapeBytes or indexedShapeId and indexedShapeType are required", e.getMessage());
}
public void testNoIndexedShapeType() throws IOException {
IllegalArgumentException e = expectThrows(IllegalArgumentException.class,
() -> new GeoShapeQueryBuilder(fieldName(), "id", null));
assertEquals("indexedShapeType is required if indexedShapeId is specified", e.getMessage());
assertEquals("either shape or indexedShapeId is required", e.getMessage());
}
public void testNoRelation() throws IOException {
@ -286,4 +284,16 @@ public class GeoShapeQueryBuilderTests extends AbstractQueryTestCase<GeoShapeQue
builder = rewriteAndFetch(builder, createShardContext());
builder.writeTo(new BytesStreamOutput(10));
}
@Override
protected QueryBuilder parseQuery(XContentParser parser) throws IOException {
QueryBuilder query = super.parseQuery(parser);
assertThat(query, instanceOf(GeoShapeQueryBuilder.class));
GeoShapeQueryBuilder shapeQuery = (GeoShapeQueryBuilder) query;
if (shapeQuery.indexedShapeType() != null) {
assertWarnings(GeoShapeQueryBuilder.TYPES_DEPRECATION_MESSAGE);
}
return query;
}
}

View File

@ -25,6 +25,7 @@ import org.apache.lucene.search.Query;
import org.apache.lucene.search.TermInSetQuery;
import org.elasticsearch.cluster.metadata.MetaData;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.mapper.IdFieldMapper;
import org.elasticsearch.search.internal.SearchContext;
import org.elasticsearch.test.AbstractQueryTestCase;
@ -152,4 +153,16 @@ public class IdsQueryBuilderTests extends AbstractQueryTestCase<IdsQueryBuilder>
assertThat(parsed.ids(), contains("1","100","4"));
assertEquals(json, 0, parsed.types().length);
}
@Override
protected QueryBuilder parseQuery(XContentParser parser) throws IOException {
QueryBuilder query = super.parseQuery(parser);
assertThat(query, instanceOf(IdsQueryBuilder.class));
IdsQueryBuilder idsQuery = (IdsQueryBuilder) query;
if (idsQuery.types().length > 0) {
assertWarnings(IdsQueryBuilder.TYPES_DEPRECATION_MESSAGE);
}
return query;
}
}

View File

@ -59,8 +59,7 @@ public class LegacyGeoShapeFieldQueryTests extends GeoShapeQueryBuilderTests {
} else {
indexedShapeToReturn = shape;
indexedShapeId = randomAlphaOfLengthBetween(3, 20);
indexedShapeType = randomAlphaOfLengthBetween(3, 20);
builder = new GeoShapeQueryBuilder(fieldName(), indexedShapeId, indexedShapeType);
builder = new GeoShapeQueryBuilder(fieldName(), indexedShapeId);
if (randomBoolean()) {
indexedShapeIndex = randomAlphaOfLengthBetween(3, 20);
builder.indexedShapeIndex(indexedShapeIndex);

View File

@ -93,14 +93,20 @@ public class MoreLikeThisQueryBuilderTests extends AbstractQueryTestCase<MoreLik
private Item generateRandomItem() {
String index = randomBoolean() ? getIndex().getName() : null;
String type = "doc";
// indexed item or artificial document
Item item;
if (randomBoolean()) {
item = new Item(index, type, randomAlphaOfLength(10));
item = randomBoolean()
? new Item(index, randomAlphaOfLength(10))
: new Item(index, randomArtificialDoc());
} else {
item = new Item(index, type, randomArtificialDoc());
String type = "doc";
item = randomBoolean()
? new Item(index, type, randomAlphaOfLength(10))
: new Item(index, type, randomArtificialDoc());
}
// if no field is specified MLT uses all mapped fields for this item
if (randomBoolean()) {
item.fields(randomFrom(randomFields));
@ -372,4 +378,16 @@ public class MoreLikeThisQueryBuilderTests extends AbstractQueryTestCase<MoreLik
assertEquals(json, 2, parsed.fields().length);
assertEquals(json, "and potentially some more text here as well", parsed.likeTexts()[0]);
}
@Override
protected QueryBuilder parseQuery(XContentParser parser) throws IOException {
QueryBuilder query = super.parseQuery(parser);
assertThat(query, instanceOf(MoreLikeThisQueryBuilder.class));
MoreLikeThisQueryBuilder mltQuery = (MoreLikeThisQueryBuilder) query;
if (mltQuery.isTypeless() == false) {
assertWarnings(MoreLikeThisQueryBuilder.TYPES_DEPRECATION_MESSAGE);
}
return query;
}
}

View File

@ -21,6 +21,7 @@ package org.elasticsearch.index.query;
import com.carrotsearch.randomizedtesting.generators.RandomNumbers;
import com.carrotsearch.randomizedtesting.generators.RandomStrings;
import org.elasticsearch.common.Strings;
import java.util.Random;
@ -47,7 +48,9 @@ public class RandomQueryBuilder {
case 1:
return new TermQueryBuilderTests().createTestQueryBuilder();
case 2:
return new IdsQueryBuilderTests().createTestQueryBuilder();
// We make sure this query has no types to avoid deprecation warnings in the
// tests that use this method.
return new IdsQueryBuilderTests().createTestQueryBuilder().types(Strings.EMPTY_ARRAY);
case 3:
return createMultiTermQuery(r);
default:

View File

@ -35,10 +35,12 @@ import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.common.io.stream.BytesStreamOutput;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.get.GetResult;
import org.elasticsearch.indices.TermsLookup;
import org.elasticsearch.search.internal.SearchContext;
import org.elasticsearch.test.AbstractQueryTestCase;
import org.hamcrest.CoreMatchers;
import org.junit.Before;
import java.io.IOException;
@ -97,8 +99,13 @@ public class TermsQueryBuilderTests extends AbstractQueryTestCase<TermsQueryBuil
}
private TermsLookup randomTermsLookup() {
return new TermsLookup(randomAlphaOfLength(10), randomAlphaOfLength(10), randomAlphaOfLength(10),
termsPath).routing(randomBoolean() ? randomAlphaOfLength(10) : null);
// Randomly choose between a typeless terms lookup and one with an explicit type to make sure we are
// testing both cases.
TermsLookup lookup = randomBoolean()
? new TermsLookup(randomAlphaOfLength(10), randomAlphaOfLength(10), termsPath)
: new TermsLookup(randomAlphaOfLength(10), randomAlphaOfLength(10), randomAlphaOfLength(10), termsPath);
lookup.routing(randomBoolean() ? randomAlphaOfLength(10) : null);
return lookup;
}
@Override
@ -316,5 +323,16 @@ public class TermsQueryBuilderTests extends AbstractQueryTestCase<TermsQueryBuil
builder.doToQuery(createShardContext());
assertWarnings(QueryShardContext.TYPES_DEPRECATION_MESSAGE);
}
}
@Override
protected QueryBuilder parseQuery(XContentParser parser) throws IOException {
QueryBuilder query = super.parseQuery(parser);
assertThat(query, CoreMatchers.instanceOf(TermsQueryBuilder.class));
TermsQueryBuilder termsQuery = (TermsQueryBuilder) query;
if (termsQuery.isTypeless() == false) {
assertWarnings(TermsQueryBuilder.TYPES_DEPRECATION_MESSAGE);
}
return query;
}
}

View File

@ -19,6 +19,7 @@
package org.elasticsearch.indices;
import org.elasticsearch.Version;
import org.elasticsearch.common.io.stream.BytesStreamOutput;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.test.ESTestCase;
@ -82,9 +83,37 @@ public class TermsLookupTests extends ESTestCase {
assertNotSame(deserializedLookup, termsLookup);
}
}
try (BytesStreamOutput output = new BytesStreamOutput()) {
output.setVersion(Version.V_6_7_0);
IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> termsLookup.writeTo(output));
assertEquals("Typeless [terms] lookup queries are not supported if any " +
"node is running a version before 7.0.", e.getMessage());
}
}
public void testSerializationWithTypes() throws IOException {
TermsLookup termsLookup = randomTermsLookupWithTypes();
try (BytesStreamOutput output = new BytesStreamOutput()) {
termsLookup.writeTo(output);
try (StreamInput in = output.bytes().streamInput()) {
TermsLookup deserializedLookup = new TermsLookup(in);
assertEquals(deserializedLookup, termsLookup);
assertEquals(deserializedLookup.hashCode(), termsLookup.hashCode());
assertNotSame(deserializedLookup, termsLookup);
}
}
}
public static TermsLookup randomTermsLookup() {
return new TermsLookup(
randomAlphaOfLength(10),
randomAlphaOfLength(10),
randomAlphaOfLength(10).replace('.', '_')
).routing(randomBoolean() ? randomAlphaOfLength(10) : null);
}
public static TermsLookup randomTermsLookupWithTypes() {
return new TermsLookup(
randomAlphaOfLength(10),
randomAlphaOfLength(10),

View File

@ -195,7 +195,44 @@ public class GeoShapeQueryTests extends ESSingleNodeTestCase {
.endObject()
.endObject()).setRefreshPolicy(IMMEDIATE).get();
SearchResponse searchResponse = client().prepareSearch("test").setTypes("type1")
SearchResponse searchResponse = client().prepareSearch("test")
.setQuery(geoIntersectionQuery("location", "Big_Rectangle"))
.get();
assertSearchResponse(searchResponse);
assertThat(searchResponse.getHits().getTotalHits().value, equalTo(1L));
assertThat(searchResponse.getHits().getHits().length, equalTo(1));
assertThat(searchResponse.getHits().getAt(0).getId(), equalTo("1"));
searchResponse = client().prepareSearch("test")
.setQuery(geoShapeQuery("location", "Big_Rectangle"))
.get();
assertSearchResponse(searchResponse);
assertThat(searchResponse.getHits().getTotalHits().value, equalTo(1L));
assertThat(searchResponse.getHits().getHits().length, equalTo(1));
assertThat(searchResponse.getHits().getAt(0).getId(), equalTo("1"));
}
public void testIndexedShapeReferenceWithTypes() throws Exception {
String mapping = Strings.toString(createMapping());
client().admin().indices().prepareCreate("test").addMapping("type1", mapping, XContentType.JSON).get();
createIndex("shapes");
ensureGreen();
EnvelopeBuilder shape = new EnvelopeBuilder(new Coordinate(-45, 45), new Coordinate(45, -45));
client().prepareIndex("shapes", "shape_type", "Big_Rectangle").setSource(jsonBuilder().startObject()
.field("shape", shape).endObject()).setRefreshPolicy(IMMEDIATE).get();
client().prepareIndex("test", "type1", "1").setSource(jsonBuilder().startObject()
.field("name", "Document 1")
.startObject("location")
.field("type", "point")
.startArray("coordinates").value(-30).value(-30).endArray()
.endObject()
.endObject()).setRefreshPolicy(IMMEDIATE).get();
SearchResponse searchResponse = client().prepareSearch("test")
.setQuery(geoIntersectionQuery("location", "Big_Rectangle", "shape_type"))
.get();
@ -225,8 +262,8 @@ public class GeoShapeQueryTests extends ESSingleNodeTestCase {
client().prepareIndex("shapes", "shape_type", "Big_Rectangle").setSource(jsonBuilder().startObject()
.field("shape", shape).endObject()).setRefreshPolicy(IMMEDIATE).get();
IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> client().prepareSearch("test").setTypes("type1")
.setQuery(geoIntersectionQuery("location", "Big_Rectangle", "shape_type")).get());
IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> client().prepareSearch("test")
.setQuery(geoIntersectionQuery("location", "Big_Rectangle")).get());
assertThat(e.getMessage(), containsString("source disabled"));
}
@ -273,28 +310,28 @@ public class GeoShapeQueryTests extends ESSingleNodeTestCase {
.endArray().endArray()
.endObject().endObject()).setRefreshPolicy(IMMEDIATE).get();
GeoShapeQueryBuilder filter = QueryBuilders.geoShapeQuery("location", "1", "type").relation(ShapeRelation.INTERSECTS)
GeoShapeQueryBuilder filter = QueryBuilders.geoShapeQuery("location", "1").relation(ShapeRelation.INTERSECTS)
.indexedShapeIndex("shapes")
.indexedShapePath("location");
SearchResponse result = client().prepareSearch("test").setQuery(QueryBuilders.matchAllQuery())
.setPostFilter(filter).get();
assertSearchResponse(result);
assertHitCount(result, 1);
filter = QueryBuilders.geoShapeQuery("location", "1", "type").relation(ShapeRelation.INTERSECTS)
filter = QueryBuilders.geoShapeQuery("location", "1").relation(ShapeRelation.INTERSECTS)
.indexedShapeIndex("shapes")
.indexedShapePath("1.location");
result = client().prepareSearch("test").setQuery(QueryBuilders.matchAllQuery())
.setPostFilter(filter).get();
assertSearchResponse(result);
assertHitCount(result, 1);
filter = QueryBuilders.geoShapeQuery("location", "1", "type").relation(ShapeRelation.INTERSECTS)
filter = QueryBuilders.geoShapeQuery("location", "1").relation(ShapeRelation.INTERSECTS)
.indexedShapeIndex("shapes")
.indexedShapePath("1.2.location");
result = client().prepareSearch("test").setQuery(QueryBuilders.matchAllQuery())
.setPostFilter(filter).get();
assertSearchResponse(result);
assertHitCount(result, 1);
filter = QueryBuilders.geoShapeQuery("location", "1", "type").relation(ShapeRelation.INTERSECTS)
filter = QueryBuilders.geoShapeQuery("location", "1").relation(ShapeRelation.INTERSECTS)
.indexedShapeIndex("shapes")
.indexedShapePath("1.2.3.location");
result = client().prepareSearch("test").setQuery(QueryBuilders.matchAllQuery())
@ -303,25 +340,25 @@ public class GeoShapeQueryTests extends ESSingleNodeTestCase {
assertHitCount(result, 1);
// now test the query variant
GeoShapeQueryBuilder query = QueryBuilders.geoShapeQuery("location", "1", "type")
GeoShapeQueryBuilder query = QueryBuilders.geoShapeQuery("location", "1")
.indexedShapeIndex("shapes")
.indexedShapePath("location");
result = client().prepareSearch("test").setQuery(query).get();
assertSearchResponse(result);
assertHitCount(result, 1);
query = QueryBuilders.geoShapeQuery("location", "1", "type")
query = QueryBuilders.geoShapeQuery("location", "1")
.indexedShapeIndex("shapes")
.indexedShapePath("1.location");
result = client().prepareSearch("test").setQuery(query).get();
assertSearchResponse(result);
assertHitCount(result, 1);
query = QueryBuilders.geoShapeQuery("location", "1", "type")
query = QueryBuilders.geoShapeQuery("location", "1")
.indexedShapeIndex("shapes")
.indexedShapePath("1.2.location");
result = client().prepareSearch("test").setQuery(query).get();
assertSearchResponse(result);
assertHitCount(result, 1);
query = QueryBuilders.geoShapeQuery("location", "1", "type")
query = QueryBuilders.geoShapeQuery("location", "1")
.indexedShapeIndex("shapes")
.indexedShapePath("1.2.3.location");
result = client().prepareSearch("test").setQuery(query).get();
@ -356,7 +393,7 @@ public class GeoShapeQueryTests extends ESSingleNodeTestCase {
GeoShapeQueryBuilder geoShapeQueryBuilder = QueryBuilders.geoShapeQuery("location", filterShape);
geoShapeQueryBuilder.relation(ShapeRelation.INTERSECTS);
SearchResponse result = client().prepareSearch("test").setTypes("type").setQuery(geoShapeQueryBuilder).get();
SearchResponse result = client().prepareSearch("test").setQuery(geoShapeQueryBuilder).get();
assertSearchResponse(result);
assertHitCount(result, 1);
}
@ -405,7 +442,7 @@ public class GeoShapeQueryTests extends ESSingleNodeTestCase {
GeoShapeQueryBuilder geoShapeQueryBuilder = QueryBuilders.geoShapeQuery("location", queryCollection);
geoShapeQueryBuilder.relation(ShapeRelation.INTERSECTS);
SearchResponse result = client().prepareSearch("test").setTypes("type").setQuery(geoShapeQueryBuilder).get();
SearchResponse result = client().prepareSearch("test").setQuery(geoShapeQueryBuilder).get();
assertSearchResponse(result);
assertTrue(result.getHits().getTotalHits().value > 0);
}
@ -429,7 +466,7 @@ public class GeoShapeQueryTests extends ESSingleNodeTestCase {
GeoShapeQueryBuilder geoShapeQueryBuilder = QueryBuilders.geoShapeQuery("location", pb);
geoShapeQueryBuilder.relation(ShapeRelation.INTERSECTS);
SearchResponse result = client().prepareSearch("test").setTypes("type").setQuery(geoShapeQueryBuilder).get();
SearchResponse result = client().prepareSearch("test").setQuery(geoShapeQueryBuilder).get();
assertSearchResponse(result);
assertHitCount(result, 1);
}
@ -454,7 +491,7 @@ public class GeoShapeQueryTests extends ESSingleNodeTestCase {
ShapeBuilder filterShape = (gcb.getShapeAt(randomIntBetween(0, gcb.numShapes() - 1)));
GeoShapeQueryBuilder filter = QueryBuilders.geoShapeQuery("location", filterShape)
.relation(ShapeRelation.CONTAINS);
SearchResponse response = client().prepareSearch("test").setTypes("type").setQuery(QueryBuilders.matchAllQuery())
SearchResponse response = client().prepareSearch("test").setQuery(QueryBuilders.matchAllQuery())
.setPostFilter(filter).get();
assertSearchResponse(response);
@ -478,7 +515,7 @@ public class GeoShapeQueryTests extends ESSingleNodeTestCase {
client().prepareIndex("test", "type", "1").setSource(docSource).setRefreshPolicy(IMMEDIATE).get();
ExistsQueryBuilder eqb = QueryBuilders.existsQuery("location");
SearchResponse result = client().prepareSearch("test").setTypes("type").setQuery(eqb).get();
SearchResponse result = client().prepareSearch("test").setQuery(eqb).get();
assertSearchResponse(result);
assertHitCount(result, 1);
}
@ -520,7 +557,7 @@ public class GeoShapeQueryTests extends ESSingleNodeTestCase {
new PolygonBuilder(new CoordinatesBuilder().coordinate(99.0, -1.0).coordinate(99.0, 3.0)
.coordinate(103.0, 3.0).coordinate(103.0, -1.0)
.coordinate(99.0, -1.0)))).relation(ShapeRelation.INTERSECTS);
SearchResponse result = client().prepareSearch("test").setTypes("type").setQuery(QueryBuilders.matchAllQuery())
SearchResponse result = client().prepareSearch("test").setQuery(QueryBuilders.matchAllQuery())
.setPostFilter(filter).get();
assertSearchResponse(result);
assertHitCount(result, 1);
@ -530,7 +567,7 @@ public class GeoShapeQueryTests extends ESSingleNodeTestCase {
new PolygonBuilder(new CoordinatesBuilder().coordinate(199.0, -11.0).coordinate(199.0, 13.0)
.coordinate(193.0, 13.0).coordinate(193.0, -11.0)
.coordinate(199.0, -11.0)))).relation(ShapeRelation.INTERSECTS);
result = client().prepareSearch("test").setTypes("type").setQuery(QueryBuilders.matchAllQuery())
result = client().prepareSearch("test").setQuery(QueryBuilders.matchAllQuery())
.setPostFilter(filter).get();
assertSearchResponse(result);
assertHitCount(result, 0);
@ -541,13 +578,13 @@ public class GeoShapeQueryTests extends ESSingleNodeTestCase {
new PolygonBuilder(new CoordinatesBuilder().coordinate(199.0, -11.0).coordinate(199.0, 13.0)
.coordinate(193.0, 13.0).coordinate(193.0, -11.0)
.coordinate(199.0, -11.0)))).relation(ShapeRelation.INTERSECTS);
result = client().prepareSearch("test").setTypes("type").setQuery(QueryBuilders.matchAllQuery())
result = client().prepareSearch("test").setQuery(QueryBuilders.matchAllQuery())
.setPostFilter(filter).get();
assertSearchResponse(result);
assertHitCount(result, 1);
// no shape
filter = QueryBuilders.geoShapeQuery("location", new GeometryCollectionBuilder());
result = client().prepareSearch("test").setTypes("type").setQuery(QueryBuilders.matchAllQuery())
result = client().prepareSearch("test").setQuery(QueryBuilders.matchAllQuery())
.setPostFilter(filter).get();
assertSearchResponse(result);
assertHitCount(result, 0);

View File

@ -87,12 +87,36 @@ public class MoreLikeThisIT extends ESIntegTestCase {
.source(jsonBuilder().startObject().field("text", "lucene release").endObject())).actionGet();
client().admin().indices().refresh(refreshRequest()).actionGet();
logger.info("Running moreLikeThis");
SearchResponse response = client().prepareSearch().setQuery(
new MoreLikeThisQueryBuilder(null, new Item[] {new Item("test", "1")}).minTermFreq(1).minDocFreq(1)).get();
assertHitCount(response, 1L);
}
public void testSimpleMoreLikeThisWithTypes() throws Exception {
logger.info("Creating index test");
assertAcked(prepareCreate("test").addMapping("type1",
jsonBuilder().startObject().startObject("type1").startObject("properties")
.startObject("text").field("type", "text").endObject()
.endObject().endObject().endObject()));
logger.info("Running Cluster Health");
assertThat(ensureGreen(), equalTo(ClusterHealthStatus.GREEN));
logger.info("Indexing...");
client().index(indexRequest("test").type("type1").id("1").source(jsonBuilder().startObject().field("text", "lucene").endObject()))
.actionGet();
client().index(indexRequest("test").type("type1").id("2")
.source(jsonBuilder().startObject().field("text", "lucene release").endObject())).actionGet();
client().admin().indices().refresh(refreshRequest()).actionGet();
logger.info("Running moreLikeThis");
SearchResponse response = client().prepareSearch().setQuery(
new MoreLikeThisQueryBuilder(null, new Item[] {new Item("test", "type1", "1")}).minTermFreq(1).minDocFreq(1)).get();
assertHitCount(response, 1L);
}
//Issue #30148
public void testMoreLikeThisForZeroTokensInOneOfTheAnalyzedFields() throws Exception {
CreateIndexRequestBuilder createIndexRequestBuilder = prepareCreate("test")
@ -116,7 +140,7 @@ public class MoreLikeThisIT extends ESIntegTestCase {
client().admin().indices().refresh(refreshRequest()).actionGet();
SearchResponse searchResponse = client().prepareSearch().setQuery(
moreLikeThisQuery(new String[]{"myField", "empty"}, null, new Item[]{new Item("test", "type", "1")})
moreLikeThisQuery(new String[]{"myField", "empty"}, null, new Item[]{new Item("test", "1")})
.minTermFreq(1).minDocFreq(1)
).get();
@ -142,7 +166,7 @@ public class MoreLikeThisIT extends ESIntegTestCase {
logger.info("Running moreLikeThis");
SearchResponse response = client().prepareSearch().setQuery(
new MoreLikeThisQueryBuilder(null, new Item[] {new Item("test", "type1", "1")}).minTermFreq(1).minDocFreq(1)).get();
new MoreLikeThisQueryBuilder(null, new Item[] {new Item("test", "1")}).minTermFreq(1).minDocFreq(1)).get();
assertHitCount(response, 0L);
}
@ -173,24 +197,24 @@ public class MoreLikeThisIT extends ESIntegTestCase {
logger.info("Running moreLikeThis on index");
SearchResponse response = client().prepareSearch().setQuery(
new MoreLikeThisQueryBuilder(null, new Item[] {new Item("test", "type1", "1")}).minTermFreq(1).minDocFreq(1)).get();
new MoreLikeThisQueryBuilder(null, new Item[] {new Item("test", "1")}).minTermFreq(1).minDocFreq(1)).get();
assertHitCount(response, 2L);
logger.info("Running moreLikeThis on beta shard");
response = client().prepareSearch("beta").setQuery(
new MoreLikeThisQueryBuilder(null, new Item[] {new Item("test", "type1", "1")}).minTermFreq(1).minDocFreq(1)).get();
new MoreLikeThisQueryBuilder(null, new Item[] {new Item("test", "1")}).minTermFreq(1).minDocFreq(1)).get();
assertHitCount(response, 1L);
assertThat(response.getHits().getAt(0).getId(), equalTo("3"));
logger.info("Running moreLikeThis on release shard");
response = client().prepareSearch("release").setQuery(
new MoreLikeThisQueryBuilder(null, new Item[] {new Item("test", "type1", "1")}).minTermFreq(1).minDocFreq(1)).get();
new MoreLikeThisQueryBuilder(null, new Item[] {new Item("test", "1")}).minTermFreq(1).minDocFreq(1)).get();
assertHitCount(response, 1L);
assertThat(response.getHits().getAt(0).getId(), equalTo("2"));
logger.info("Running moreLikeThis on alias with node client");
response = internalCluster().coordOnlyNodeClient().prepareSearch("beta").setQuery(
new MoreLikeThisQueryBuilder(null, new Item[] {new Item("test", "type1", "1")}).minTermFreq(1).minDocFreq(1)).get();
new MoreLikeThisQueryBuilder(null, new Item[] {new Item("test", "1")}).minTermFreq(1).minDocFreq(1)).get();
assertHitCount(response, 1L);
assertThat(response.getHits().getAt(0).getId(), equalTo("3"));
}
@ -311,13 +335,13 @@ public class MoreLikeThisIT extends ESIntegTestCase {
// Implicit list of fields -> ignore numeric fields
SearchResponse searchResponse = client().prepareSearch().setQuery(
new MoreLikeThisQueryBuilder(null, new Item[] {new Item("test", "type", "1")}).minTermFreq(1).minDocFreq(1)).get();
new MoreLikeThisQueryBuilder(null, new Item[] {new Item("test", "1")}).minTermFreq(1).minDocFreq(1)).get();
assertHitCount(searchResponse, 1L);
// Explicit list of fields including numeric fields -> fail
assertThrows(client().prepareSearch().setQuery(
new MoreLikeThisQueryBuilder(new String[] {"string_value", "int_value"}, null,
new Item[] {new Item("test", "type", "1")}).minTermFreq(1).minDocFreq(1)), SearchPhaseExecutionException.class);
new Item[] {new Item("test", "1")}).minTermFreq(1).minDocFreq(1)), SearchPhaseExecutionException.class);
// mlt query with no field -> No results (because _all is not enabled)
searchResponse = client().prepareSearch().setQuery(moreLikeThisQuery(new String[] {"index"}).minTermFreq(1).minDocFreq(1))
@ -417,7 +441,7 @@ public class MoreLikeThisIT extends ESIntegTestCase {
logger.info("Running More Like This with include true");
SearchResponse response = client().prepareSearch().setQuery(
new MoreLikeThisQueryBuilder(null, new Item[] {new Item("test", "type1", "1")}).minTermFreq(1).minDocFreq(1).include(true)
new MoreLikeThisQueryBuilder(null, new Item[] {new Item("test", "1")}).minTermFreq(1).minDocFreq(1).include(true)
.minimumShouldMatch("0%")).get();
assertOrderedSearchHits(response, "1", "2");
@ -428,7 +452,7 @@ public class MoreLikeThisIT extends ESIntegTestCase {
logger.info("Running More Like This with include false");
response = client().prepareSearch().setQuery(
new MoreLikeThisQueryBuilder(null, new Item[] {new Item("test", "type1", "1")}).minTermFreq(1).minDocFreq(1)
new MoreLikeThisQueryBuilder(null, new Item[] {new Item("test", "1")}).minTermFreq(1).minDocFreq(1)
.minimumShouldMatch("0%")).get();
assertSearchHits(response, "2");
}
@ -673,7 +697,7 @@ public class MoreLikeThisIT extends ESIntegTestCase {
.field("text1", "elasticsearch")
.endObject()));
MoreLikeThisQueryBuilder mltQuery = moreLikeThisQuery(new Item[] {new Item("test", "type1", "1")})
MoreLikeThisQueryBuilder mltQuery = moreLikeThisQuery(new Item[] {new Item("test", "1")})
.minTermFreq(0)
.minDocFreq(0)
.include(true)
@ -683,7 +707,7 @@ public class MoreLikeThisIT extends ESIntegTestCase {
assertSearchResponse(response);
assertHitCount(response, 2);
mltQuery = moreLikeThisQuery(new String[] {"text"}, null, new Item[] {new Item("test", "type1", "1")})
mltQuery = moreLikeThisQuery(new String[] {"text"}, null, new Item[] {new Item("test", "1")})
.minTermFreq(0)
.minDocFreq(0)
.include(true)
@ -724,19 +748,19 @@ public class MoreLikeThisIT extends ESIntegTestCase {
logger.info("Running moreLikeThis with one item without routing attribute");
SearchPhaseExecutionException exception = expectThrows(SearchPhaseExecutionException.class, () ->
client().prepareSearch().setQuery(new MoreLikeThisQueryBuilder(null, new Item[]{
new Item("test", "type1", "1")
new Item("test", "1")
}).minTermFreq(1).minDocFreq(1)).get());
Throwable cause = exception.getCause();
assertThat(cause, instanceOf(RoutingMissingException.class));
assertThat(cause.getMessage(), equalTo("routing is required for [test]/[type1]/[1]"));
assertThat(cause.getMessage(), equalTo("routing is required for [test]/[_doc]/[1]"));
}
{
logger.info("Running moreLikeThis with one item with routing attribute and two items without routing attribute");
SearchPhaseExecutionException exception = expectThrows(SearchPhaseExecutionException.class, () ->
client().prepareSearch().setQuery(new MoreLikeThisQueryBuilder(null, new Item[]{
new Item("test", "type1", "1").routing("1"),
new Item("test", "1").routing("1"),
new Item("test", "type1", "2"),
new Item("test", "type1", "3")
}).minTermFreq(1).minDocFreq(1)).get());

View File

@ -379,7 +379,7 @@ public abstract class AbstractQueryTestCase<QB extends AbstractQueryBuilder<QB>>
/**
* Parses the query provided as bytes argument and compares it with the expected result provided as argument as a {@link QueryBuilder}
*/
private static void assertParsedQuery(XContentParser parser, QueryBuilder expectedQuery) throws IOException {
private void assertParsedQuery(XContentParser parser, QueryBuilder expectedQuery) throws IOException {
QueryBuilder newQuery = parseQuery(parser);
assertNotSame(newQuery, expectedQuery);
assertEquals(expectedQuery, newQuery);
@ -396,7 +396,7 @@ public abstract class AbstractQueryTestCase<QB extends AbstractQueryBuilder<QB>>
return parseQuery(parser);
}
protected static QueryBuilder parseQuery(XContentParser parser) throws IOException {
protected QueryBuilder parseQuery(XContentParser parser) throws IOException {
QueryBuilder parseInnerQueryBuilder = parseInnerQueryBuilder(parser);
assertNull(parser.nextToken());
return parseInnerQueryBuilder;