Remove core delete-by-query implementation, to be replaced with a plugin

The current implementation is dangerous: it unexpectedly refreshes,
which can quickly cause an unhealthy index (segment explosion).  It
can also delete different documents on primary vs replicas, causing
inconsistent replicas.

For 2.0 we will replace this with an optional plugin that does a
scan/scroll search and then issues bulk delete requests.

Closes #10859
This commit is contained in:
Michael McCandless 2015-04-28 16:09:04 -04:00 committed by mikemccand
parent 7d8f39fc27
commit cf2fb4ed0f
51 changed files with 12 additions and 2401 deletions

View File

@ -1,75 +0,0 @@
{
"delete_by_query": {
"documentation": "http://www.elastic.co/guide/en/elasticsearch/reference/master/docs-delete-by-query.html",
"methods": ["DELETE"],
"url": {
"path": "/{index}/_query",
"paths": ["/{index}/_query", "/{index}/{type}/_query"],
"parts": {
"index": {
"type" : "list",
"required": true,
"description" : "A comma-separated list of indices to restrict the operation; use `_all` to perform the operation on all indices"
},
"type": {
"type" : "list",
"description" : "A comma-separated list of types to restrict the operation"
}
},
"params": {
"analyzer": {
"type" : "string",
"description" : "The analyzer to use for the query string"
},
"consistency": {
"type" : "enum",
"options" : ["one", "quorum", "all"],
"description" : "Specific write consistency setting for the operation"
},
"default_operator": {
"type" : "enum",
"options" : ["AND","OR"],
"default" : "OR",
"description" : "The default operator for query string query (AND or OR)"
},
"df": {
"type" : "string",
"description" : "The field to use as default where no field prefix is given in the query string"
},
"ignore_unavailable": {
"type" : "boolean",
"description" : "Whether specified concrete indices should be ignored when unavailable (missing or closed)"
},
"allow_no_indices": {
"type" : "boolean",
"description" : "Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified)"
},
"expand_wildcards": {
"type" : "enum",
"options" : ["open","closed","none","all"],
"default" : "open",
"description" : "Whether to expand wildcard expression to concrete indices that are open, closed or both."
},
"q": {
"type" : "string",
"description" : "Query in the Lucene query string syntax"
},
"routing": {
"type" : "string",
"description" : "Specific routing value"
},
"source": {
"type" : "string",
"description" : "The URL-encoded query definition (instead of using the request body)"
},
"timeout": {
"type" : "time",
"description" : "Explicit operation timeout"
}
}
},
"body": {
"description" : "A query to restrict the operation specified with the Query DSL"
}
}
}

View File

@ -1,42 +0,0 @@
---
"Basic delete_by_query":
- do:
index:
index: test_1
type: test
id: 1
body: { foo: bar }
- do:
index:
index: test_1
type: test
id: 2
body: { foo: baz }
- do:
index:
index: test_1
type: test
id: 3
body: { foo: foo }
- do:
indices.refresh: {}
- do:
delete_by_query:
index: test_1
body:
query:
match:
foo: bar
- do:
indices.refresh: {}
- do:
count:
index: test_1
- match: { count: 2 }

View File

@ -124,10 +124,6 @@ import org.elasticsearch.action.count.CountAction;
import org.elasticsearch.action.count.TransportCountAction;
import org.elasticsearch.action.delete.DeleteAction;
import org.elasticsearch.action.delete.TransportDeleteAction;
import org.elasticsearch.action.deletebyquery.DeleteByQueryAction;
import org.elasticsearch.action.deletebyquery.TransportDeleteByQueryAction;
import org.elasticsearch.action.deletebyquery.TransportIndexDeleteByQueryAction;
import org.elasticsearch.action.deletebyquery.TransportShardDeleteByQueryAction;
import org.elasticsearch.action.exists.ExistsAction;
import org.elasticsearch.action.exists.TransportExistsAction;
import org.elasticsearch.action.explain.ExplainAction;
@ -284,8 +280,6 @@ public class ActionModule extends AbstractModule {
TransportShardMultiGetAction.class);
registerAction(BulkAction.INSTANCE, TransportBulkAction.class,
TransportShardBulkAction.class);
registerAction(DeleteByQueryAction.INSTANCE, TransportDeleteByQueryAction.class,
TransportIndexDeleteByQueryAction.class, TransportShardDeleteByQueryAction.class);
registerAction(SearchAction.INSTANCE, TransportSearchAction.class,
TransportSearchDfsQueryThenFetchAction.class,
TransportSearchQueryThenFetchAction.class,

View File

@ -1,45 +0,0 @@
/*
* 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.action.deletebyquery;
import org.elasticsearch.action.ClientAction;
import org.elasticsearch.client.Client;
/**
*/
public class DeleteByQueryAction extends ClientAction<DeleteByQueryRequest, DeleteByQueryResponse, DeleteByQueryRequestBuilder> {
public static final DeleteByQueryAction INSTANCE = new DeleteByQueryAction();
public static final String NAME = "indices:data/write/delete/by_query";
private DeleteByQueryAction() {
super(NAME);
}
@Override
public DeleteByQueryResponse newResponse() {
return new DeleteByQueryResponse();
}
@Override
public DeleteByQueryRequestBuilder newRequestBuilder(Client client) {
return new DeleteByQueryRequestBuilder(client);
}
}

View File

@ -1,218 +0,0 @@
/*
* 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.action.deletebyquery;
import com.google.common.base.Charsets;
import org.elasticsearch.ElasticsearchGenerationException;
import org.elasticsearch.action.ActionRequest;
import org.elasticsearch.action.ActionRequestValidationException;
import org.elasticsearch.action.support.QuerySourceBuilder;
import org.elasticsearch.action.support.replication.IndicesReplicationOperationRequest;
import org.elasticsearch.client.Requests;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentHelper;
import java.io.IOException;
import java.util.Arrays;
import java.util.Map;
import static org.elasticsearch.action.ValidateActions.addValidationError;
/**
* A request to delete all documents that matching a specific query. Best created with
* {@link org.elasticsearch.client.Requests#deleteByQueryRequest(String...)}.
* <p/>
* <p>The request requires the source to be set either using {@link #source(QuerySourceBuilder)},
* or {@link #source(byte[])}.
*
* @see DeleteByQueryResponse
* @see org.elasticsearch.client.Requests#deleteByQueryRequest(String...)
* @see org.elasticsearch.client.Client#deleteByQuery(DeleteByQueryRequest)
*/
public class DeleteByQueryRequest extends IndicesReplicationOperationRequest<DeleteByQueryRequest> {
private BytesReference source;
private String[] types = Strings.EMPTY_ARRAY;
@Nullable
private String routing;
/**
* Constructs a new delete by query request to run against the provided indices. No indices means
* it will run against all indices.
*/
public DeleteByQueryRequest(String... indices) {
this.indices = indices;
}
public DeleteByQueryRequest() {
}
/**
* Copy constructor that creates a new delete by query request that is a copy of the one provided as an argument.
* The new request will inherit though headers and context from the original request that caused it.
*/
public DeleteByQueryRequest(ActionRequest originalRequest) {
super(originalRequest);
}
@Override
public ActionRequestValidationException validate() {
ActionRequestValidationException validationException = super.validate();
if (source == null) {
validationException = addValidationError("source is missing", validationException);
}
return validationException;
}
/**
* The source to execute.
*/
public BytesReference source() {
return source;
}
/**
* The source to execute.
*/
public DeleteByQueryRequest source(QuerySourceBuilder sourceBuilder) {
this.source = sourceBuilder.buildAsBytes(Requests.CONTENT_TYPE);
return this;
}
/**
* The source to execute. It is preferable to use either {@link #source(byte[])}
* or {@link #source(QuerySourceBuilder)}.
*/
public DeleteByQueryRequest source(String query) {
this.source = new BytesArray(query.getBytes(Charsets.UTF_8));
return this;
}
/**
* The source to execute in the form of a map.
*/
@SuppressWarnings("unchecked")
public DeleteByQueryRequest source(Map source) {
try {
XContentBuilder builder = XContentFactory.contentBuilder(Requests.CONTENT_TYPE);
builder.map(source);
return source(builder);
} catch (IOException e) {
throw new ElasticsearchGenerationException("Failed to generate [" + source + "]", e);
}
}
public DeleteByQueryRequest source(XContentBuilder builder) {
this.source = builder.bytes();
return this;
}
/**
* The source to execute.
*/
public DeleteByQueryRequest source(byte[] source) {
return source(source, 0, source.length);
}
/**
* The source to execute.
*/
public DeleteByQueryRequest source(byte[] source, int offset, int length) {
return source(new BytesArray(source, offset, length));
}
public DeleteByQueryRequest source(BytesReference source) {
this.source = source;
return this;
}
/**
* The types of documents the query will run against. Defaults to all types.
*/
public String[] types() {
return this.types;
}
/**
* A comma separated list of routing values to control the shards the search will be executed on.
*/
public String routing() {
return this.routing;
}
/**
* A comma separated list of routing values to control the shards the search will be executed on.
*/
public DeleteByQueryRequest routing(String routing) {
this.routing = routing;
return this;
}
/**
* The routing values to control the shards that the search will be executed on.
*/
public DeleteByQueryRequest routing(String... routings) {
this.routing = Strings.arrayToCommaDelimitedString(routings);
return this;
}
/**
* The types of documents the query will run against. Defaults to all types.
*/
public DeleteByQueryRequest types(String... types) {
this.types = types;
return this;
}
@Override
public void readFrom(StreamInput in) throws IOException {
super.readFrom(in);
source = in.readBytesReference();
routing = in.readOptionalString();
types = in.readStringArray();
}
@Override
public void writeTo(StreamOutput out) throws IOException {
super.writeTo(out);
out.writeBytesReference(source);
out.writeOptionalString(routing);
out.writeStringArray(types);
}
@Override
public String toString() {
String sSource = "_na_";
try {
sSource = XContentHelper.convertToJson(source, false);
} catch (Exception e) {
// ignore
}
return "[" + Arrays.toString(indices) + "][" + Arrays.toString(types) + "], source[" + sSource + "]";
}
}

View File

@ -1,149 +0,0 @@
/*
* 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.action.deletebyquery;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.WriteConsistencyLevel;
import org.elasticsearch.action.support.QuerySourceBuilder;
import org.elasticsearch.action.support.replication.IndicesReplicationOperationRequestBuilder;
import org.elasticsearch.client.Client;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import java.util.Map;
/**
*
*/
public class DeleteByQueryRequestBuilder extends IndicesReplicationOperationRequestBuilder<DeleteByQueryRequest, DeleteByQueryResponse, DeleteByQueryRequestBuilder> {
private QuerySourceBuilder sourceBuilder;
public DeleteByQueryRequestBuilder(Client client) {
super(client, new DeleteByQueryRequest());
}
/**
* The types of documents the query will run against. Defaults to all types.
*/
public DeleteByQueryRequestBuilder setTypes(String... types) {
request.types(types);
return this;
}
/**
* A comma separated list of routing values to control the shards the action will be executed on.
*/
public DeleteByQueryRequestBuilder setRouting(String routing) {
request.routing(routing);
return this;
}
/**
* The routing values to control the shards that the action will be executed on.
*/
public DeleteByQueryRequestBuilder setRouting(String... routing) {
request.routing(routing);
return this;
}
/**
* The query to delete documents for.
*
* @see org.elasticsearch.index.query.QueryBuilders
*/
public DeleteByQueryRequestBuilder setQuery(QueryBuilder queryBuilder) {
sourceBuilder().setQuery(queryBuilder);
return this;
}
/**
* The source to execute. It is preferable to use either {@link #setSource(byte[])}
* or {@link #setQuery(QueryBuilder)}.
*/
public DeleteByQueryRequestBuilder setSource(String source) {
request().source(source);
return this;
}
/**
* The source to execute in the form of a map.
*/
public DeleteByQueryRequestBuilder setSource(Map<String, Object> source) {
request().source(source);
return this;
}
/**
* The source to execute in the form of a builder.
*/
public DeleteByQueryRequestBuilder setSource(XContentBuilder builder) {
request().source(builder);
return this;
}
/**
* The source to execute.
*/
public DeleteByQueryRequestBuilder setSource(byte[] source) {
request().source(source);
return this;
}
/**
* The source to execute.
*/
public DeleteByQueryRequestBuilder setSource(BytesReference source) {
request().source(source);
return this;
}
/**
* The source to execute.
*/
public DeleteByQueryRequestBuilder setSource(byte[] source, int offset, int length) {
request().source(source, offset, length);
return this;
}
@Override
public DeleteByQueryRequestBuilder setConsistencyLevel(WriteConsistencyLevel consistencyLevel) {
request.consistencyLevel(consistencyLevel);
return this;
}
@Override
protected void doExecute(ActionListener<DeleteByQueryResponse> listener) {
if (sourceBuilder != null) {
request.source(sourceBuilder);
}
client.deleteByQuery(request, listener);
}
private QuerySourceBuilder sourceBuilder() {
if (sourceBuilder == null) {
sourceBuilder = new QuerySourceBuilder();
}
return sourceBuilder;
}
}

View File

@ -1,93 +0,0 @@
/*
* 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.action.deletebyquery;
import org.elasticsearch.action.ActionResponse;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.rest.RestStatus;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
import static com.google.common.collect.Maps.newHashMap;
/**
* The response of delete by query action. Holds the {@link IndexDeleteByQueryResponse}s from all the
* different indices.
*/
public class DeleteByQueryResponse extends ActionResponse implements Iterable<IndexDeleteByQueryResponse> {
private Map<String, IndexDeleteByQueryResponse> indices = newHashMap();
DeleteByQueryResponse() {
}
@Override
public Iterator<IndexDeleteByQueryResponse> iterator() {
return indices.values().iterator();
}
/**
* The responses from all the different indices.
*/
public Map<String, IndexDeleteByQueryResponse> getIndices() {
return indices;
}
/**
* The response of a specific index.
*/
public IndexDeleteByQueryResponse getIndex(String index) {
return indices.get(index);
}
public RestStatus status() {
RestStatus status = RestStatus.OK;
for (IndexDeleteByQueryResponse indexResponse : indices.values()) {
if (indexResponse.getShardInfo().status().getStatus() > status.getStatus()) {
status = indexResponse.getShardInfo().status();
}
}
return status;
}
@Override
public void readFrom(StreamInput in) throws IOException {
super.readFrom(in);
int size = in.readVInt();
for (int i = 0; i < size; i++) {
IndexDeleteByQueryResponse response = new IndexDeleteByQueryResponse();
response.readFrom(in);
indices.put(response.getIndex(), response);
}
}
@Override
public void writeTo(StreamOutput out) throws IOException {
super.writeTo(out);
out.writeVInt(indices.size());
for (IndexDeleteByQueryResponse indexResponse : indices.values()) {
indexResponse.writeTo(out);
}
}
}

View File

@ -1,70 +0,0 @@
/*
* 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.action.deletebyquery;
import org.elasticsearch.action.support.replication.IndexReplicationOperationRequest;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.bytes.BytesReference;
import java.util.Set;
/**
* Delete by query request to execute on a specific index.
*/
class IndexDeleteByQueryRequest extends IndexReplicationOperationRequest<IndexDeleteByQueryRequest> {
private final BytesReference source;
private final String[] types;
@Nullable
private final Set<String> routing;
@Nullable
private final String[] filteringAliases;
private final long nowInMillis;
IndexDeleteByQueryRequest(DeleteByQueryRequest request, String index, @Nullable Set<String> routing, @Nullable String[] filteringAliases,
long nowInMillis) {
super(index, request.timeout(), request.consistencyLevel(), request.indices(), request.indicesOptions(), request);
this.source = request.source();
this.types = request.types();
this.routing = routing;
this.filteringAliases = filteringAliases;
this.nowInMillis = nowInMillis;
}
BytesReference source() {
return source;
}
Set<String> routing() {
return this.routing;
}
String[] types() {
return this.types;
}
String[] filteringAliases() {
return filteringAliases;
}
long nowInMillis() {
return nowInMillis;
}
}

View File

@ -1,61 +0,0 @@
/*
* 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.action.deletebyquery;
import org.elasticsearch.action.ActionWriteResponse;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import java.io.IOException;
/**
* Delete by query response executed on a specific index.
*/
public class IndexDeleteByQueryResponse extends ActionWriteResponse {
private String index;
IndexDeleteByQueryResponse(String index, ShardInfo failures) {
this.index = index;
setShardInfo(failures);
}
IndexDeleteByQueryResponse() {
}
/**
* The index the delete by query operation was executed against.
*/
public String getIndex() {
return this.index;
}
@Override
public void readFrom(StreamInput in) throws IOException {
super.readFrom(in);
index = in.readString();
}
@Override
public void writeTo(StreamOutput out) throws IOException {
super.writeTo(out);
out.writeString(index);
}
}

View File

@ -1,177 +0,0 @@
/*
* 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.action.deletebyquery;
import org.elasticsearch.action.ActionRequestValidationException;
import org.elasticsearch.action.OriginalIndices;
import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.action.support.replication.ShardReplicationOperationRequest;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.xcontent.XContentHelper;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import static org.elasticsearch.action.ValidateActions.addValidationError;
/**
* Delete by query request to execute on a specific shard.
*/
public class ShardDeleteByQueryRequest extends ShardReplicationOperationRequest<ShardDeleteByQueryRequest> {
private int shardId;
private BytesReference source;
private String[] types = Strings.EMPTY_ARRAY;
@Nullable
private Set<String> routing;
@Nullable
private String[] filteringAliases;
private long nowInMillis;
private OriginalIndices originalIndices;
ShardDeleteByQueryRequest(IndexDeleteByQueryRequest request, int shardId) {
super(request);
this.index = request.index();
this.source = request.source();
this.types = request.types();
this.shardId = shardId;
consistencyLevel(request.consistencyLevel());
timeout = request.timeout();
this.routing = request.routing();
filteringAliases = request.filteringAliases();
nowInMillis = request.nowInMillis();
this.originalIndices = new OriginalIndices(request);
}
ShardDeleteByQueryRequest() {
}
@Override
public ActionRequestValidationException validate() {
ActionRequestValidationException validationException = super.validate();
if (source == null) {
addValidationError("source is missing", validationException);
}
return validationException;
}
public int shardId() {
return this.shardId;
}
BytesReference source() {
return source;
}
public String[] types() {
return this.types;
}
public Set<String> routing() {
return this.routing;
}
public String[] filteringAliases() {
return filteringAliases;
}
long nowInMillis() {
return nowInMillis;
}
@Override
public String[] indices() {
return originalIndices.indices();
}
@Override
public IndicesOptions indicesOptions() {
return originalIndices.indicesOptions();
}
@Override
public void readFrom(StreamInput in) throws IOException {
super.readFrom(in);
source = in.readBytesReference();
shardId = in.readVInt();
types = in.readStringArray();
int routingSize = in.readVInt();
if (routingSize > 0) {
routing = new HashSet<>(routingSize);
for (int i = 0; i < routingSize; i++) {
routing.add(in.readString());
}
}
int aliasesSize = in.readVInt();
if (aliasesSize > 0) {
filteringAliases = new String[aliasesSize];
for (int i = 0; i < aliasesSize; i++) {
filteringAliases[i] = in.readString();
}
}
nowInMillis = in.readVLong();
originalIndices = OriginalIndices.readOriginalIndices(in);
}
@Override
public void writeTo(StreamOutput out) throws IOException {
super.writeTo(out);
out.writeBytesReference(source);
out.writeVInt(shardId);
out.writeStringArray(types);
if (routing != null) {
out.writeVInt(routing.size());
for (String r : routing) {
out.writeString(r);
}
} else {
out.writeVInt(0);
}
if (filteringAliases != null) {
out.writeVInt(filteringAliases.length);
for (String alias : filteringAliases) {
out.writeString(alias);
}
} else {
out.writeVInt(0);
}
out.writeVLong(nowInMillis);
OriginalIndices.writeOriginalIndices(originalIndices, out);
}
@Override
public String toString() {
String sSource = "_na_";
try {
sSource = XContentHelper.convertToJson(source, false);
} catch (Exception e) {
// ignore
}
return "delete_by_query {[" + index + "]" + Arrays.toString(types) + ", query [" + sSource + "]}";
}
}

View File

@ -1,29 +0,0 @@
/*
* 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.action.deletebyquery;
import org.elasticsearch.action.ActionWriteResponse;
/**
* Delete by query response executed on a specific shard.
*/
public class ShardDeleteByQueryResponse extends ActionWriteResponse {
}

View File

@ -1,98 +0,0 @@
/*
* 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.action.deletebyquery;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.support.ActionFilters;
import org.elasticsearch.action.support.DestructiveOperations;
import org.elasticsearch.action.support.replication.TransportIndicesReplicationOperationAction;
import org.elasticsearch.cluster.ClusterService;
import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.block.ClusterBlockException;
import org.elasticsearch.cluster.block.ClusterBlockLevel;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.node.settings.NodeSettingsService;
import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.transport.TransportService;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReferenceArray;
/**
*/
public class TransportDeleteByQueryAction extends TransportIndicesReplicationOperationAction<DeleteByQueryRequest, DeleteByQueryResponse, IndexDeleteByQueryRequest, IndexDeleteByQueryResponse, ShardDeleteByQueryRequest, ShardDeleteByQueryResponse> {
private final DestructiveOperations destructiveOperations;
@Inject
public TransportDeleteByQueryAction(Settings settings, ClusterService clusterService, TransportService transportService,
ThreadPool threadPool, TransportIndexDeleteByQueryAction indexDeleteByQueryAction,
NodeSettingsService nodeSettingsService, ActionFilters actionFilters) {
super(settings, DeleteByQueryAction.NAME, transportService, clusterService, threadPool, indexDeleteByQueryAction, actionFilters, DeleteByQueryRequest.class);
this.destructiveOperations = new DestructiveOperations(logger, settings, nodeSettingsService);
}
@Override
protected void doExecute(DeleteByQueryRequest request, ActionListener<DeleteByQueryResponse> listener) {
destructiveOperations.failDestructive(request.indices());
super.doExecute(request, listener);
}
@Override
protected Map<String, Set<String>> resolveRouting(ClusterState clusterState, DeleteByQueryRequest request) throws ElasticsearchException {
return clusterState.metaData().resolveSearchRouting(request.routing(), request.indices());
}
@Override
protected DeleteByQueryResponse newResponseInstance(DeleteByQueryRequest request, AtomicReferenceArray indexResponses) {
DeleteByQueryResponse response = new DeleteByQueryResponse();
for (int i = 0; i < indexResponses.length(); i++) {
IndexDeleteByQueryResponse indexResponse = (IndexDeleteByQueryResponse) indexResponses.get(i);
if (indexResponse != null) {
response.getIndices().put(indexResponse.getIndex(), indexResponse);
}
}
return response;
}
@Override
protected boolean accumulateExceptions() {
return false;
}
@Override
protected ClusterBlockException checkGlobalBlock(ClusterState state, DeleteByQueryRequest replicationPingRequest) {
return state.blocks().globalBlockedException(ClusterBlockLevel.READ);
}
@Override
protected ClusterBlockException checkRequestBlock(ClusterState state, DeleteByQueryRequest request, String[] concreteIndices) {
return state.blocks().indicesBlockedException(ClusterBlockLevel.WRITE, concreteIndices);
}
@Override
protected IndexDeleteByQueryRequest newIndexRequestInstance(DeleteByQueryRequest request, String index, Set<String> routing, long startTimeInMillis) {
String[] filteringAliases = clusterService.state().metaData().filteringAliases(index, request.indices());
return new IndexDeleteByQueryRequest(request, index, routing, filteringAliases, startTimeInMillis);
}
}

View File

@ -1,73 +0,0 @@
/*
* 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.action.deletebyquery;
import org.elasticsearch.action.ActionWriteResponse;
import org.elasticsearch.action.support.ActionFilters;
import org.elasticsearch.action.support.replication.TransportIndexReplicationOperationAction;
import org.elasticsearch.cluster.ClusterService;
import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.block.ClusterBlockException;
import org.elasticsearch.cluster.block.ClusterBlockLevel;
import org.elasticsearch.cluster.routing.GroupShardsIterator;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.threadpool.ThreadPool;
import java.util.List;
/**
* Internal transport action that broadcasts a delete by query request to all of the shards that belong to an index.
*/
public class TransportIndexDeleteByQueryAction extends TransportIndexReplicationOperationAction<IndexDeleteByQueryRequest, IndexDeleteByQueryResponse, ShardDeleteByQueryRequest, ShardDeleteByQueryResponse> {
private static final String ACTION_NAME = DeleteByQueryAction.NAME + "[index]";
@Inject
public TransportIndexDeleteByQueryAction(Settings settings, ClusterService clusterService,
ThreadPool threadPool, TransportShardDeleteByQueryAction shardDeleteByQueryAction, ActionFilters actionFilters) {
super(settings, ACTION_NAME, clusterService, threadPool, shardDeleteByQueryAction, actionFilters);
}
@Override
protected IndexDeleteByQueryResponse newResponseInstance(IndexDeleteByQueryRequest request, List<ShardDeleteByQueryResponse> shardDeleteByQueryResponses, ActionWriteResponse.ShardInfo shardInfo) {
return new IndexDeleteByQueryResponse(request.index(), shardInfo);
}
@Override
protected ClusterBlockException checkGlobalBlock(ClusterState state, IndexDeleteByQueryRequest request) {
return state.blocks().globalBlockedException(ClusterBlockLevel.WRITE);
}
@Override
protected ClusterBlockException checkRequestBlock(ClusterState state, IndexDeleteByQueryRequest request) {
return state.blocks().indexBlockedException(ClusterBlockLevel.WRITE, request.index());
}
@Override
protected GroupShardsIterator shards(IndexDeleteByQueryRequest request) {
return clusterService.operationRouting().deleteByQueryShards(clusterService.state(), request.index(), request.routing());
}
@Override
protected ShardDeleteByQueryRequest newShardRequestInstance(IndexDeleteByQueryRequest request, int shardId) {
return new ShardDeleteByQueryRequest(request, shardId);
}
}

View File

@ -1,139 +0,0 @@
/*
* 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.action.deletebyquery;
import org.elasticsearch.ElasticsearchIllegalStateException;
import org.elasticsearch.action.support.ActionFilters;
import org.elasticsearch.action.support.replication.TransportShardReplicationOperationAction;
import org.elasticsearch.cache.recycler.PageCacheRecycler;
import org.elasticsearch.cluster.ClusterService;
import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.action.shard.ShardStateAction;
import org.elasticsearch.cluster.routing.GroupShardsIterator;
import org.elasticsearch.cluster.routing.ShardIterator;
import org.elasticsearch.common.collect.Tuple;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.util.BigArrays;
import org.elasticsearch.index.engine.Engine;
import org.elasticsearch.index.query.ParsedQuery;
import org.elasticsearch.index.IndexService;
import org.elasticsearch.index.shard.IndexShard;
import org.elasticsearch.index.shard.ShardId;
import org.elasticsearch.indices.IndicesService;
import org.elasticsearch.script.ScriptService;
import org.elasticsearch.search.internal.DefaultSearchContext;
import org.elasticsearch.search.internal.SearchContext;
import org.elasticsearch.search.internal.ShardSearchLocalRequest;
import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.transport.TransportService;
/**
*
*/
public class TransportShardDeleteByQueryAction extends TransportShardReplicationOperationAction<ShardDeleteByQueryRequest, ShardDeleteByQueryRequest, ShardDeleteByQueryResponse> {
public final static String DELETE_BY_QUERY_API = "delete_by_query";
private static final String ACTION_NAME = DeleteByQueryAction.NAME + "[s]";
private final ScriptService scriptService;
private final PageCacheRecycler pageCacheRecycler;
private final BigArrays bigArrays;
@Inject
public TransportShardDeleteByQueryAction(Settings settings, TransportService transportService,
ClusterService clusterService, IndicesService indicesService, ThreadPool threadPool,
ShardStateAction shardStateAction, ScriptService scriptService,
PageCacheRecycler pageCacheRecycler, BigArrays bigArrays, ActionFilters actionFilters) {
super(settings, ACTION_NAME, transportService, clusterService, indicesService, threadPool, shardStateAction, actionFilters,
ShardDeleteByQueryRequest.class, ShardDeleteByQueryRequest.class, ThreadPool.Names.INDEX);
this.scriptService = scriptService;
this.pageCacheRecycler = pageCacheRecycler;
this.bigArrays = bigArrays;
}
@Override
protected boolean checkWriteConsistency() {
return true;
}
@Override
protected ShardDeleteByQueryResponse newResponseInstance() {
return new ShardDeleteByQueryResponse();
}
@Override
protected boolean resolveIndex() {
return false;
}
@Override
protected Tuple<ShardDeleteByQueryResponse, ShardDeleteByQueryRequest> shardOperationOnPrimary(ClusterState clusterState, PrimaryOperationRequest shardRequest) {
ShardDeleteByQueryRequest request = shardRequest.request;
IndexService indexService = indicesService.indexServiceSafe(shardRequest.shardId.getIndex());
IndexShard indexShard = indexService.shardSafe(shardRequest.shardId.id());
SearchContext.setCurrent(new DefaultSearchContext(0, new ShardSearchLocalRequest(request.types(), request.nowInMillis()), null,
indexShard.acquireSearcher(DELETE_BY_QUERY_API), indexService, indexShard, scriptService,
pageCacheRecycler, bigArrays, threadPool.estimatedTimeInMillisCounter()));
try {
Engine.DeleteByQuery deleteByQuery = indexShard.prepareDeleteByQuery(request.source(), request.filteringAliases(), Engine.Operation.Origin.PRIMARY, request.types());
SearchContext.current().parsedQuery(new ParsedQuery(deleteByQuery.query()));
indexShard.deleteByQuery(deleteByQuery);
} finally {
try (SearchContext searchContext = SearchContext.current()) {
SearchContext.removeCurrent();
}
}
return new Tuple<>(new ShardDeleteByQueryResponse(), shardRequest.request);
}
@Override
protected void shardOperationOnReplica(ShardId shardId, ShardDeleteByQueryRequest request) {
IndexService indexService = indicesService.indexServiceSafe(shardId.getIndex());
IndexShard indexShard = indexService.shardSafe(shardId.id());
SearchContext.setCurrent(new DefaultSearchContext(0, new ShardSearchLocalRequest(request.types(), request.nowInMillis()), null,
indexShard.acquireSearcher(DELETE_BY_QUERY_API, true), indexService, indexShard, scriptService,
pageCacheRecycler, bigArrays, threadPool.estimatedTimeInMillisCounter()));
try {
Engine.DeleteByQuery deleteByQuery = indexShard.prepareDeleteByQuery(request.source(), request.filteringAliases(), Engine.Operation.Origin.REPLICA, request.types());
SearchContext.current().parsedQuery(new ParsedQuery(deleteByQuery.query()));
indexShard.deleteByQuery(deleteByQuery);
} finally {
try (SearchContext searchContext = SearchContext.current()) {
SearchContext.removeCurrent();
}
}
}
@Override
protected ShardIterator shards(ClusterState clusterState, InternalRequest request) {
GroupShardsIterator group = clusterService.operationRouting().deleteByQueryShards(clusterService.state(), request.concreteIndex(), request.request().routing());
for (ShardIterator shardIt : group) {
if (shardIt.shardId().id() == request.request().shardId()) {
return shardIt;
}
}
throw new ElasticsearchIllegalStateException("No shards iterator found for shard [" + request.request().shardId() + "]");
}
}

View File

@ -1,23 +0,0 @@
/*
* 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.
*/
/**
* Delete by query action.
*/
package org.elasticsearch.action.deletebyquery;

View File

@ -29,9 +29,6 @@ import org.elasticsearch.action.count.CountResponse;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteRequestBuilder;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.deletebyquery.DeleteByQueryRequest;
import org.elasticsearch.action.deletebyquery.DeleteByQueryRequestBuilder;
import org.elasticsearch.action.deletebyquery.DeleteByQueryResponse;
import org.elasticsearch.action.exists.ExistsRequest;
import org.elasticsearch.action.exists.ExistsRequestBuilder;
import org.elasticsearch.action.exists.ExistsResponse;
@ -223,29 +220,6 @@ public interface Client extends ElasticsearchClient<Client>, Releasable {
*/
BulkRequestBuilder prepareBulk();
/**
* Deletes all documents from one or more indices based on a query.
*
* @param request The delete by query request
* @return The result future
* @see Requests#deleteByQueryRequest(String...)
*/
ActionFuture<DeleteByQueryResponse> deleteByQuery(DeleteByQueryRequest request);
/**
* Deletes all documents from one or more indices based on a query.
*
* @param request The delete by query request
* @param listener A listener to be notified with a result
* @see Requests#deleteByQueryRequest(String...)
*/
void deleteByQuery(DeleteByQueryRequest request, ActionListener<DeleteByQueryResponse> listener);
/**
* Deletes all documents from one or more indices based on a query.
*/
DeleteByQueryRequestBuilder prepareDeleteByQuery(String... indices);
/**
* Gets the document that was indexed from an index with a type and id.
*

View File

@ -52,7 +52,6 @@ import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsRequest
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.count.CountRequest;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.deletebyquery.DeleteByQueryRequest;
import org.elasticsearch.action.exists.ExistsRequest;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.index.IndexRequest;
@ -112,18 +111,6 @@ public class Requests {
return new BulkRequest();
}
/**
* Creates a delete by query request. Note, the query itself must be set either by setting the JSON source
* of the query, or by using a {@link org.elasticsearch.index.query.QueryBuilder} (using {@link org.elasticsearch.index.query.QueryBuilders}).
*
* @param indices The indices the delete by query against. Use <tt>null</tt> or <tt>_all</tt> to execute against all indices
* @return The delete by query request
* @see org.elasticsearch.client.Client#deleteByQuery(org.elasticsearch.action.deletebyquery.DeleteByQueryRequest)
*/
public static DeleteByQueryRequest deleteByQueryRequest(String... indices) {
return new DeleteByQueryRequest(indices);
}
/**
* Creates a get request to get the JSON source from an index based on a type and id. Note, the
* {@link GetRequest#type(String)} and {@link GetRequest#id(String)} must be set.

View File

@ -32,10 +32,6 @@ import org.elasticsearch.action.delete.DeleteAction;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteRequestBuilder;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.deletebyquery.DeleteByQueryAction;
import org.elasticsearch.action.deletebyquery.DeleteByQueryRequest;
import org.elasticsearch.action.deletebyquery.DeleteByQueryRequestBuilder;
import org.elasticsearch.action.deletebyquery.DeleteByQueryResponse;
import org.elasticsearch.action.exists.ExistsAction;
import org.elasticsearch.action.exists.ExistsRequest;
import org.elasticsearch.action.exists.ExistsRequestBuilder;
@ -172,21 +168,6 @@ public abstract class AbstractClient implements Client {
return new BulkRequestBuilder(this);
}
@Override
public ActionFuture<DeleteByQueryResponse> deleteByQuery(final DeleteByQueryRequest request) {
return execute(DeleteByQueryAction.INSTANCE, request);
}
@Override
public void deleteByQuery(final DeleteByQueryRequest request, final ActionListener<DeleteByQueryResponse> listener) {
execute(DeleteByQueryAction.INSTANCE, request, listener);
}
@Override
public DeleteByQueryRequestBuilder prepareDeleteByQuery(String... indices) {
return new DeleteByQueryRequestBuilder(this).setIndices(indices);
}
@Override
public ActionFuture<GetResponse> get(final GetRequest request) {
return execute(GetAction.INSTANCE, request);

View File

@ -29,8 +29,6 @@ import org.elasticsearch.action.count.CountRequest;
import org.elasticsearch.action.count.CountResponse;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.deletebyquery.DeleteByQueryRequest;
import org.elasticsearch.action.deletebyquery.DeleteByQueryResponse;
import org.elasticsearch.action.explain.ExplainRequest;
import org.elasticsearch.action.explain.ExplainResponse;
import org.elasticsearch.action.get.GetRequest;
@ -352,16 +350,6 @@ public class TransportClient extends AbstractClient {
internalClient.bulk(request, listener);
}
@Override
public ActionFuture<DeleteByQueryResponse> deleteByQuery(DeleteByQueryRequest request) {
return internalClient.deleteByQuery(request);
}
@Override
public void deleteByQuery(DeleteByQueryRequest request, ActionListener<DeleteByQueryResponse> listener) {
internalClient.deleteByQuery(request, listener);
}
@Override
public ActionFuture<GetResponse> get(GetRequest request) {
return internalClient.get(request);

View File

@ -78,25 +78,6 @@ public class OperationRouting extends AbstractComponent {
return indexRoutingTable(clusterState, index).groupByShardsIt();
}
public GroupShardsIterator deleteByQueryShards(ClusterState clusterState, String index, @Nullable Set<String> routing) throws IndexMissingException {
if (routing == null || routing.isEmpty()) {
return indexRoutingTable(clusterState, index).groupByShardsIt();
}
// we use set here and not identity set since we might get duplicates
HashSet<ShardIterator> set = new HashSet<>();
IndexRoutingTable indexRouting = indexRoutingTable(clusterState, index);
for (String r : routing) {
int shardId = shardId(clusterState, index, null, null, r);
IndexShardRoutingTable indexShard = indexRouting.shard(shardId);
if (indexShard == null) {
throw new IndexShardMissingException(new ShardId(index, shardId));
}
set.add(indexShard.shardsRandomIt());
}
return new GroupShardsIterator(Lists.newArrayList(set));
}
public int searchShardsCount(ClusterState clusterState, String[] indices, String[] concreteIndices, @Nullable Map<String, Set<String>> routing, @Nullable String preference) throws IndexMissingException {
final Set<IndexShardRoutingTable> shards = computeTargetedShards(clusterState, concreteIndices, routing);
return shards.size();

View File

@ -21,12 +21,9 @@ package org.elasticsearch.index.engine;
import org.elasticsearch.index.shard.ShardId;
/**
*
*/
public class DeleteByQueryFailedEngineException extends EngineException {
public DeleteByQueryFailedEngineException(ShardId shardId, Engine.DeleteByQuery deleteByQuery, Throwable cause) {
super(shardId, "Delete by query failed for [" + deleteByQuery.query() + "]", cause);
}
}
}

View File

@ -205,6 +205,8 @@ public abstract class Engine implements Closeable {
public abstract void delete(Delete delete) throws EngineException;
/** @deprecated This was removed, but we keep this API so translog can replay any DBQs on upgrade. */
@Deprecated
public abstract void delete(DeleteByQuery delete) throws EngineException;
final protected GetResult getFromSearcher(Get get) throws EngineException {

View File

@ -537,6 +537,8 @@ public class InternalEngine extends Engine {
}
}
/** @deprecated This was removed, but we keep this API so translog can replay any DBQs on upgrade. */
@Deprecated
@Override
public void delete(DeleteByQuery delete) throws EngineException {
try (ReleasableLock lock = readLock.acquire()) {

View File

@ -117,6 +117,8 @@ public class ShadowEngine extends Engine {
throw new UnsupportedOperationException(shardId + " delete operation not allowed on shadow engine");
}
/** @deprecated This was removed, but we keep this API so translog can replay any DBQs on upgrade. */
@Deprecated
@Override
public void delete(DeleteByQuery delete) throws EngineException {
throw new UnsupportedOperationException(shardId + " delete-by-query operation not allowed on shadow engine");

View File

@ -96,12 +96,4 @@ public abstract class IndexingOperationListener {
public void postDelete(Engine.Delete delete) {
}
public Engine.DeleteByQuery preDeleteByQuery(Engine.DeleteByQuery deleteByQuery) {
return deleteByQuery;
}
public void postDeleteByQuery(Engine.DeleteByQuery deleteByQuery) {
}
}

View File

@ -216,19 +216,6 @@ public class ShardIndexingService extends AbstractIndexShardComponent {
typeStats(delete.type()).deleteCurrent.dec();
}
public Engine.DeleteByQuery preDeleteByQuery(Engine.DeleteByQuery deleteByQuery) {
for (IndexingOperationListener listener : listeners) {
deleteByQuery = listener.preDeleteByQuery(deleteByQuery);
}
return deleteByQuery;
}
public void postDeleteByQuery(Engine.DeleteByQuery deleteByQuery) {
for (IndexingOperationListener listener : listeners) {
listener.postDeleteByQuery(deleteByQuery);
}
}
public void noopUpdate(String type) {
totalStats.noopUpdates.inc();
typeStats(type).noopUpdates.inc();

View File

@ -345,15 +345,5 @@ public class PercolatorQueriesRegistry extends AbstractIndexShardComponent imple
removePercolateQuery(delete.id());
}
}
// Updating the live percolate queries for a delete by query is tricky with the current way delete by queries
// are handled. It is only possible if we put a big lock around the post delete by query hook...
// If we implement delete by query, that just runs a query and generates delete operations in a bulk, then
// updating the live percolator is automatically supported for delete by query.
// @Override
// public void postDeleteByQuery(Engine.DeleteByQuery deleteByQuery) {
// }
}
}

View File

@ -41,8 +41,6 @@ import org.elasticsearch.search.internal.SubSearchContext;
import java.io.IOException;
import static org.elasticsearch.index.query.QueryParserUtils.ensureNotDeleteByQuery;
/**
*
*/
@ -64,7 +62,6 @@ public class HasChildFilterParser implements FilterParser {
@Override
public Filter parse(QueryParseContext parseContext) throws IOException, QueryParsingException {
ensureNotDeleteByQuery(NAME, parseContext);
XContentParser parser = parseContext.parser();
boolean queryFound = false;

View File

@ -42,8 +42,6 @@ import org.elasticsearch.search.internal.SubSearchContext;
import java.io.IOException;
import static org.elasticsearch.index.query.QueryParserUtils.ensureNotDeleteByQuery;
/**
*
*/
@ -65,7 +63,6 @@ public class HasChildQueryParser implements QueryParser {
@Override
public Query parse(QueryParseContext parseContext) throws IOException, QueryParsingException {
ensureNotDeleteByQuery(NAME, parseContext);
XContentParser parser = parseContext.parser();
boolean queryFound = false;

View File

@ -32,7 +32,6 @@ import org.elasticsearch.search.internal.SubSearchContext;
import java.io.IOException;
import static org.elasticsearch.index.query.HasParentQueryParser.createParentQuery;
import static org.elasticsearch.index.query.QueryParserUtils.ensureNotDeleteByQuery;
/**
*
@ -55,7 +54,6 @@ public class HasParentFilterParser implements FilterParser {
@Override
public Filter parse(QueryParseContext parseContext) throws IOException, QueryParsingException {
ensureNotDeleteByQuery(NAME, parseContext);
XContentParser parser = parseContext.parser();
boolean queryFound = false;
@ -129,4 +127,4 @@ public class HasParentFilterParser implements FilterParser {
return new CustomQueryWrappingFilter(parentQuery);
}
}
}

View File

@ -44,8 +44,6 @@ import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
import static org.elasticsearch.index.query.QueryParserUtils.ensureNotDeleteByQuery;
public class HasParentQueryParser implements QueryParser {
public static final String NAME = "has_parent";
@ -64,7 +62,6 @@ public class HasParentQueryParser implements QueryParser {
@Override
public Query parse(QueryParseContext parseContext) throws IOException, QueryParsingException {
ensureNotDeleteByQuery(NAME, parseContext);
XContentParser parser = parseContext.parser();
boolean queryFound = false;
@ -206,4 +203,4 @@ public class HasParentQueryParser implements QueryParser {
}
}
}
}

View File

@ -1,48 +0,0 @@
/*
* 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.action.deletebyquery.TransportShardDeleteByQueryAction;
import org.elasticsearch.search.internal.SearchContext;
/**
*/
public final class QueryParserUtils {
private QueryParserUtils() {
}
/**
* Ensures that the query parsing wasn't invoked via the delete by query api.
*/
public static void ensureNotDeleteByQuery(String name, QueryParseContext parseContext) {
SearchContext context = SearchContext.current();
if (context == null) {
// We can't do the api check, because there is no search context.
// Because the delete by query shard transport action sets the search context this isn't an issue.
return;
}
if (TransportShardDeleteByQueryAction.DELETE_BY_QUERY_API.equals(context.source())) {
throw new QueryParsingException(parseContext.index(), "[" + name + "] query and filter unsupported in delete_by_query api");
}
}
}

View File

@ -35,8 +35,6 @@ import org.elasticsearch.index.search.child.TopChildrenQuery;
import java.io.IOException;
import static org.elasticsearch.index.query.QueryParserUtils.ensureNotDeleteByQuery;
/**
*
*/
@ -55,7 +53,6 @@ public class TopChildrenQueryParser implements QueryParser {
@Override
public Query parse(QueryParseContext parseContext) throws IOException, QueryParsingException {
ensureNotDeleteByQuery(NAME, parseContext);
XContentParser parser = parseContext.parser();
boolean queryFound = false;

View File

@ -565,17 +565,6 @@ public class IndexShard extends AbstractIndexShardComponent {
return new Engine.DeleteByQuery(query, source, filteringAliases, aliasFilter, parentFilter, origin, startTime, types);
}
public void deleteByQuery(Engine.DeleteByQuery deleteByQuery) throws ElasticsearchException {
writeAllowed(deleteByQuery.origin());
if (logger.isTraceEnabled()) {
logger.trace("delete_by_query [{}]", deleteByQuery.query());
}
deleteByQuery = indexingService.preDeleteByQuery(deleteByQuery);
engine().delete(deleteByQuery);
deleteByQuery.endTime(System.nanoTime());
indexingService.postDeleteByQuery(deleteByQuery);
}
public Engine.GetResult get(Engine.Get get) throws ElasticsearchException {
readAllowed();
return engine().get(get);

View File

@ -662,6 +662,8 @@ public interface Translog extends IndexShardComponent, Closeable, Accountable {
}
}
/** @deprecated Delete-by-query is removed in 2.0, but we keep this so translog can replay on upgrade. */
@Deprecated
static class DeleteByQuery implements Operation {
public static final int SERIALIZATION_FORMAT = 2;

View File

@ -81,7 +81,6 @@ import org.elasticsearch.rest.action.admin.indices.recovery.RestRecoveryAction;
import org.elasticsearch.rest.action.bulk.RestBulkAction;
import org.elasticsearch.rest.action.cat.*;
import org.elasticsearch.rest.action.delete.RestDeleteAction;
import org.elasticsearch.rest.action.deletebyquery.RestDeleteByQueryAction;
import org.elasticsearch.rest.action.explain.RestExplainAction;
import org.elasticsearch.rest.action.fieldstats.RestFieldStatsAction;
import org.elasticsearch.rest.action.get.RestGetAction;
@ -194,7 +193,6 @@ public class RestActionModule extends AbstractModule {
bind(RestHeadAction.class).asEagerSingleton();
bind(RestMultiGetAction.class).asEagerSingleton();
bind(RestDeleteAction.class).asEagerSingleton();
bind(RestDeleteByQueryAction.class).asEagerSingleton();
bind(org.elasticsearch.rest.action.count.RestCountAction.class).asEagerSingleton();
bind(RestSuggestAction.class).asEagerSingleton();
bind(RestTermVectorsAction.class).asEagerSingleton();

View File

@ -1,103 +0,0 @@
/*
* 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.rest.action.deletebyquery;
import org.elasticsearch.action.WriteConsistencyLevel;
import org.elasticsearch.action.deletebyquery.DeleteByQueryRequest;
import org.elasticsearch.action.deletebyquery.DeleteByQueryResponse;
import org.elasticsearch.action.deletebyquery.IndexDeleteByQueryResponse;
import org.elasticsearch.action.deletebyquery.ShardDeleteByQueryRequest;
import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.action.support.QuerySourceBuilder;
import org.elasticsearch.client.Client;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentBuilderString;
import org.elasticsearch.rest.*;
import org.elasticsearch.rest.action.support.RestActions;
import org.elasticsearch.rest.action.support.RestBuilderListener;
import static org.elasticsearch.rest.RestRequest.Method.DELETE;
/**
*
*/
public class RestDeleteByQueryAction extends BaseRestHandler {
@Inject
public RestDeleteByQueryAction(Settings settings, RestController controller, Client client) {
super(settings, controller, client);
controller.registerHandler(DELETE, "/{index}/_query", this);
controller.registerHandler(DELETE, "/{index}/{type}/_query", this);
}
@Override
public void handleRequest(final RestRequest request, final RestChannel channel, final Client client) {
DeleteByQueryRequest deleteByQueryRequest = new DeleteByQueryRequest(Strings.splitStringByCommaToArray(request.param("index")));
deleteByQueryRequest.listenerThreaded(false);
if (RestActions.hasBodyContent(request)) {
deleteByQueryRequest.source(RestActions.getRestContent(request));
} else {
QuerySourceBuilder querySourceBuilder = RestActions.parseQuerySource(request);
if (querySourceBuilder != null) {
deleteByQueryRequest.source(querySourceBuilder);
}
}
deleteByQueryRequest.types(Strings.splitStringByCommaToArray(request.param("type")));
deleteByQueryRequest.timeout(request.paramAsTime("timeout", ShardDeleteByQueryRequest.DEFAULT_TIMEOUT));
deleteByQueryRequest.routing(request.param("routing"));
String consistencyLevel = request.param("consistency");
if (consistencyLevel != null) {
deleteByQueryRequest.consistencyLevel(WriteConsistencyLevel.fromString(consistencyLevel));
}
deleteByQueryRequest.indicesOptions(IndicesOptions.fromRequest(request, deleteByQueryRequest.indicesOptions()));
client.deleteByQuery(deleteByQueryRequest, new RestBuilderListener<DeleteByQueryResponse>(channel) {
@Override
public RestResponse buildResponse(DeleteByQueryResponse result, XContentBuilder builder) throws Exception {
RestStatus restStatus = result.status();
builder.startObject();
builder.startObject(Fields._INDICES);
for (IndexDeleteByQueryResponse indexDeleteByQueryResponse : result.getIndices().values()) {
builder.startObject(indexDeleteByQueryResponse.getIndex(), XContentBuilder.FieldCaseConversion.NONE);
indexDeleteByQueryResponse.getShardInfo().toXContent(builder, request);
builder.endObject();
builder.endObject();
}
builder.endObject();
return new BytesRestResponse(restStatus, builder);
}
});
}
static final class Fields {
static final XContentBuilderString _INDICES = new XContentBuilderString("_indices");
static final XContentBuilderString _SHARDS = new XContentBuilderString("_shards");
static final XContentBuilderString TOTAL = new XContentBuilderString("total");
static final XContentBuilderString SUCCESSFUL = new XContentBuilderString("successful");
static final XContentBuilderString FAILED = new XContentBuilderString("failed");
static final XContentBuilderString FAILURES = new XContentBuilderString("failures");
static final XContentBuilderString INDEX = new XContentBuilderString("index");
static final XContentBuilderString SHARD = new XContentBuilderString("shard");
static final XContentBuilderString REASON = new XContentBuilderString("reason");
}
}

View File

@ -61,8 +61,6 @@ import org.elasticsearch.action.count.CountAction;
import org.elasticsearch.action.count.CountRequest;
import org.elasticsearch.action.delete.DeleteAction;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.deletebyquery.DeleteByQueryAction;
import org.elasticsearch.action.deletebyquery.DeleteByQueryRequest;
import org.elasticsearch.action.exists.ExistsAction;
import org.elasticsearch.action.exists.ExistsRequest;
import org.elasticsearch.action.explain.ExplainAction;
@ -259,18 +257,6 @@ public class IndicesRequestTests extends ElasticsearchIntegrationTest {
assertSameIndices(updateRequest, updateShardActions);
}
@Test
public void testDeleteByQuery() {
String[] deleteByQueryShardActions = new String[]{DeleteByQueryAction.NAME + "[s]", DeleteByQueryAction.NAME + "[s][r]"};
interceptTransportActions(deleteByQueryShardActions);
DeleteByQueryRequest deleteByQueryRequest = new DeleteByQueryRequest(randomIndicesOrAliases()).source(new QuerySourceBuilder().setQuery(QueryBuilders.matchAllQuery()));
internalCluster().clientNodeClient().deleteByQuery(deleteByQueryRequest).actionGet();
clearInterceptedActions();
assertSameIndices(deleteByQueryRequest, deleteByQueryShardActions);
}
@Test
public void testBulk() {
String[] bulkShardActions = new String[]{BulkAction.NAME + "[s]", BulkAction.NAME + "[s][r]"};

View File

@ -405,26 +405,6 @@ public class IndexAliasesTests extends ElasticsearchIntegrationTest {
logger.info("--> checking counts before delete");
assertThat(client().prepareCount("bars").setQuery(QueryBuilders.matchAllQuery()).get().getCount(), equalTo(1L));
logger.info("--> delete by query from a single alias");
client().prepareDeleteByQuery("bars").setQuery(QueryBuilders.termQuery("name", "test")).get();
logger.info("--> verify that only one record was deleted");
assertThat(client().prepareCount("test1").setQuery(QueryBuilders.matchAllQuery()).get().getCount(), equalTo(3L));
logger.info("--> delete by query from an aliases pointing to two indices");
client().prepareDeleteByQuery("foos").setQuery(QueryBuilders.matchAllQuery()).get();
logger.info("--> verify that proper records were deleted");
SearchResponse searchResponse = client().prepareSearch("aliasToTests").setQuery(QueryBuilders.matchAllQuery()).get();
assertHits(searchResponse.getHits(), "3", "4", "6", "7", "8");
logger.info("--> delete by query from an aliases and an index");
client().prepareDeleteByQuery("tests", "test2").setQuery(QueryBuilders.matchAllQuery()).get();
logger.info("--> verify that proper records were deleted");
searchResponse = client().prepareSearch("aliasToTests").setQuery(QueryBuilders.matchAllQuery()).get();
assertHits(searchResponse.getHits(), "4");
}

View File

@ -31,8 +31,6 @@ import org.elasticsearch.action.admin.indices.settings.get.GetSettingsResponse;
import org.elasticsearch.action.admin.indices.stats.IndicesStatsResponse;
import org.elasticsearch.action.count.CountResponse;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.deletebyquery.DeleteByQueryResponse;
import org.elasticsearch.action.deletebyquery.IndexDeleteByQueryResponse;
import org.elasticsearch.action.explain.ExplainResponse;
import org.elasticsearch.action.get.*;
import org.elasticsearch.action.index.IndexRequestBuilder;
@ -478,36 +476,6 @@ public class BasicBackwardsCompatibilityTest extends ElasticsearchBackwardsCompa
return client().admin().cluster().prepareState().get().getState().nodes().masterNode().getVersion();
}
@Test
public void testDeleteByQuery() throws ExecutionException, InterruptedException {
createIndex("test");
ensureYellow("test");
int numDocs = iterations(10, 50);
IndexRequestBuilder[] indexRequestBuilders = new IndexRequestBuilder[numDocs + 1];
for (int i = 0; i < numDocs; i++) {
indexRequestBuilders[i] = client().prepareIndex("test", "test", Integer.toString(i)).setSource("field", "value");
}
indexRequestBuilders[numDocs] = client().prepareIndex("test", "test", Integer.toString(numDocs)).setSource("field", "other_value");
indexRandom(true, indexRequestBuilders);
SearchResponse searchResponse = client().prepareSearch("test").get();
assertNoFailures(searchResponse);
assertThat(searchResponse.getHits().totalHits(), equalTo((long) numDocs + 1));
DeleteByQueryResponse deleteByQueryResponse = client().prepareDeleteByQuery("test").setQuery(QueryBuilders.termQuery("field", "value")).get();
assertThat(deleteByQueryResponse.getIndices().size(), equalTo(1));
for (IndexDeleteByQueryResponse indexDeleteByQueryResponse : deleteByQueryResponse) {
assertThat(indexDeleteByQueryResponse.getIndex(), equalTo("test"));
assertThat(indexDeleteByQueryResponse.getShardInfo().getFailures().length, equalTo(0));
}
refresh();
searchResponse = client().prepareSearch("test").get();
assertNoFailures(searchResponse);
assertThat(searchResponse.getHits().totalHits(), equalTo(1l));
}
@Test
public void testDeleteRoutingRequired() throws ExecutionException, InterruptedException, IOException {
createIndexWithAlias();

View File

@ -1,114 +0,0 @@
/*
* 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.bwcompat;
import org.elasticsearch.Version;
import org.elasticsearch.action.index.IndexRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.test.ElasticsearchBackwardsCompatIntegrationTest;
import org.junit.BeforeClass;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
import static org.elasticsearch.index.query.QueryBuilders.hasChildQuery;
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.*;
import static org.hamcrest.core.Is.is;
/**
*/
public class ParentChildDeleteByQueryBackwardsCompatibilityTest extends ElasticsearchBackwardsCompatIntegrationTest {
@BeforeClass
public static void checkVersion() {
assumeTrue("parent child queries in delete by query is forbidden from 1.1.2 and up", globalCompatibilityVersion().onOrBefore(Version.V_1_1_1));
}
@Override
public void assertAllShardsOnNodes(String index, String pattern) {
super.assertAllShardsOnNodes(index, pattern);
}
@Override
protected Settings externalNodeSettings(int nodeOrdinal) {
return ImmutableSettings.builder()
.put(super.externalNodeSettings(nodeOrdinal))
.put("index.translog.disable_flush", true)
.build();
}
@Test
public void testHasChild() throws Exception {
assertAcked(prepareCreate("idx")
.setSettings(ImmutableSettings.builder()
.put(indexSettings())
.put("index.refresh_interval", "-1")
.put("index.routing.allocation.exclude._name", backwardsCluster().newNodePattern())
)
.addMapping("parent")
.addMapping("child", "_parent", "type=parent"));
List<IndexRequestBuilder> requests = new ArrayList<>();
requests.add(client().prepareIndex("idx", "parent", "1").setSource("{}"));
requests.add(client().prepareIndex("idx", "child", "1").setParent("1").setSource("{}"));
indexRandom(true, requests);
SearchResponse response = client().prepareSearch("idx")
.setQuery(hasChildQuery("child", matchAllQuery()))
.get();
assertNoFailures(response);
assertHitCount(response, 1);
client().prepareDeleteByQuery("idx")
.setQuery(hasChildQuery("child", matchAllQuery()))
.get();
refresh();
response = client().prepareSearch("idx")
.setQuery(hasChildQuery("child", matchAllQuery()))
.get();
assertNoFailures(response);
assertHitCount(response, 0);
client().prepareIndex("idx", "type", "1").setSource("{}").get();
assertThat(client().prepareGet("idx", "type", "1").get().isExists(), is(true));
backwardsCluster().upgradeAllNodes();
backwardsCluster().allowOnAllNodes("idx");
ensureGreen("idx");
response = client().prepareSearch("idx")
.setQuery(hasChildQuery("child", matchAllQuery()))
.get();
assertNoFailures(response);
assertHitCount(response, 1); // The delete by query has failed on recovery so that parent doc is still there
// But the rest of the recovery did execute, we just skipped over the delete by query with the p/c query.
assertThat(client().prepareGet("idx", "type", "1").get().isExists(), is(true));
response = client().prepareSearch("idx").setTypes("type").get();
assertNoFailures(response);
assertHitCount(response, 1);
}
}

View File

@ -1,204 +0,0 @@
/*
* 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.deleteByQuery;
import org.apache.lucene.util.LuceneTestCase.Slow;
import org.elasticsearch.action.ActionWriteResponse;
import org.elasticsearch.action.admin.indices.alias.Alias;
import org.elasticsearch.action.deletebyquery.DeleteByQueryRequestBuilder;
import org.elasticsearch.action.deletebyquery.DeleteByQueryResponse;
import org.elasticsearch.action.deletebyquery.IndexDeleteByQueryResponse;
import org.elasticsearch.action.index.IndexRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.indices.IndexMissingException;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.test.ElasticsearchIntegrationTest;
import org.junit.Test;
import java.util.concurrent.ExecutionException;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.*;
import static org.hamcrest.Matchers.*;
@Slow
public class DeleteByQueryTests extends ElasticsearchIntegrationTest {
@Test
public void testDeleteAllNoIndices() {
client().admin().indices().prepareRefresh().execute().actionGet();
DeleteByQueryRequestBuilder deleteByQueryRequestBuilder = client().prepareDeleteByQuery();
deleteByQueryRequestBuilder.setQuery(QueryBuilders.matchAllQuery());
deleteByQueryRequestBuilder.setIndicesOptions(IndicesOptions.fromOptions(false, true, true, false));
DeleteByQueryResponse actionGet = deleteByQueryRequestBuilder.execute().actionGet();
assertThat(actionGet.getIndices().size(), equalTo(0));
}
@Test
public void testDeleteAllOneIndex() {
String json = "{" + "\"user\":\"kimchy\"," + "\"postDate\":\"2013-01-30\"," + "\"message\":\"trying out Elastic Search\"" + "}";
final long iters = randomIntBetween(1, 50);
for (int i = 0; i < iters; i++) {
client().prepareIndex("twitter", "tweet", "" + i).setSource(json).execute().actionGet();
}
refresh();
SearchResponse search = client().prepareSearch().setQuery(QueryBuilders.matchAllQuery()).execute().actionGet();
assertThat(search.getHits().totalHits(), equalTo(iters));
DeleteByQueryRequestBuilder deleteByQueryRequestBuilder = client().prepareDeleteByQuery();
deleteByQueryRequestBuilder.setQuery(QueryBuilders.matchAllQuery());
DeleteByQueryResponse response = deleteByQueryRequestBuilder.execute().actionGet();
assertThat(response.status(), equalTo(RestStatus.OK));
assertSyncShardInfo(response.getIndex("twitter").getShardInfo(), getNumShards("twitter"));
client().admin().indices().prepareRefresh().execute().actionGet();
search = client().prepareSearch().setQuery(QueryBuilders.matchAllQuery()).execute().actionGet();
assertThat(search.getHits().totalHits(), equalTo(0l));
}
@Test
public void testMissing() {
String json = "{" + "\"user\":\"kimchy\"," + "\"postDate\":\"2013-01-30\"," + "\"message\":\"trying out Elastic Search\"" + "}";
client().prepareIndex("twitter", "tweet").setSource(json).setRefresh(true).execute().actionGet();
SearchResponse search = client().prepareSearch().setQuery(QueryBuilders.matchAllQuery()).execute().actionGet();
assertThat(search.getHits().totalHits(), equalTo(1l));
DeleteByQueryRequestBuilder deleteByQueryRequestBuilder = client().prepareDeleteByQuery();
deleteByQueryRequestBuilder.setIndices("twitter", "missing");
deleteByQueryRequestBuilder.setQuery(QueryBuilders.matchAllQuery());
try {
deleteByQueryRequestBuilder.execute().actionGet();
fail("Exception should have been thrown.");
} catch (IndexMissingException e) {
//everything well
}
deleteByQueryRequestBuilder.setIndicesOptions(IndicesOptions.lenientExpandOpen());
DeleteByQueryResponse response = deleteByQueryRequestBuilder.execute().actionGet();
assertThat(response.status(), equalTo(RestStatus.OK));
assertSyncShardInfo(response.getIndex("twitter").getShardInfo(), getNumShards("twitter"));
client().admin().indices().prepareRefresh().execute().actionGet();
search = client().prepareSearch().setQuery(QueryBuilders.matchAllQuery()).execute().actionGet();
assertThat(search.getHits().totalHits(), equalTo(0l));
}
@Test
public void testFailure() throws Exception {
assertAcked(prepareCreate("test").addAlias(new Alias("alias")));
DeleteByQueryResponse response = client().prepareDeleteByQuery(indexOrAlias())
.setQuery(QueryBuilders.hasChildQuery("type", QueryBuilders.matchAllQuery()))
.execute().actionGet();
NumShards twitter = getNumShards("test");
assertThat(response.status(), equalTo(RestStatus.BAD_REQUEST));
assertThat(response.getIndex("test").getShardInfo().getSuccessful(), equalTo(0));
assertThat(response.getIndex("test").getShardInfo().getFailures().length, equalTo(twitter.numPrimaries));
assertThat(response.getIndices().size(), equalTo(1));
assertThat(response.getIndices().get("test").getShardInfo().getFailures().length, equalTo(twitter.numPrimaries));
for (ActionWriteResponse.ShardInfo.Failure failure : response.getIndices().get("test").getShardInfo().getFailures()) {
assertThat(failure.reason(), containsString("[has_child] query and filter unsupported in delete_by_query api"));
assertThat(failure.status(), equalTo(RestStatus.BAD_REQUEST));
assertThat(failure.shardId(), greaterThan(-1));
}
}
@Test
public void testDeleteByFieldQuery() throws Exception {
assertAcked(prepareCreate("test").addAlias(new Alias("alias")));
int numDocs = scaledRandomIntBetween(10, 100);
for (int i = 0; i < numDocs; i++) {
client().prepareIndex("test", "test", Integer.toString(i))
.setRouting(randomAsciiOfLengthBetween(1, 5))
.setSource("foo", "bar").get();
}
refresh();
assertHitCount(client().prepareCount("test").setQuery(QueryBuilders.matchQuery("_id", Integer.toString(between(0, numDocs - 1)))).get(), 1);
assertHitCount(client().prepareCount("test").setQuery(QueryBuilders.matchAllQuery()).get(), numDocs);
DeleteByQueryResponse deleteByQueryResponse = client().prepareDeleteByQuery(indexOrAlias())
.setQuery(QueryBuilders.matchQuery("_id", Integer.toString(between(0, numDocs - 1)))).get();
assertThat(deleteByQueryResponse.getIndices().size(), equalTo(1));
assertThat(deleteByQueryResponse.getIndex("test"), notNullValue());
refresh();
assertHitCount(client().prepareCount("test").setQuery(QueryBuilders.matchAllQuery()).get(), numDocs - 1);
}
@Test
public void testDateMath() throws Exception {
index("test", "type", "1", "d", "2013-01-01");
ensureGreen();
refresh();
assertHitCount(client().prepareCount("test").get(), 1);
client().prepareDeleteByQuery("test").setQuery(QueryBuilders.rangeQuery("d").to("now-1h")).get();
refresh();
assertHitCount(client().prepareCount("test").get(), 0);
}
@Test
public void testDeleteByTermQuery() throws ExecutionException, InterruptedException {
createIndex("test");
ensureGreen();
int numDocs = iterations(10, 50);
IndexRequestBuilder[] indexRequestBuilders = new IndexRequestBuilder[numDocs + 1];
for (int i = 0; i < numDocs; i++) {
indexRequestBuilders[i] = client().prepareIndex("test", "test", Integer.toString(i)).setSource("field", "value");
}
indexRequestBuilders[numDocs] = client().prepareIndex("test", "test", Integer.toString(numDocs)).setSource("field", "other_value");
indexRandom(true, indexRequestBuilders);
SearchResponse searchResponse = client().prepareSearch("test").get();
assertNoFailures(searchResponse);
assertThat(searchResponse.getHits().totalHits(), equalTo((long)numDocs + 1));
DeleteByQueryResponse deleteByQueryResponse = client().prepareDeleteByQuery("test").setQuery(QueryBuilders.termQuery("field", "value")).get();
assertThat(deleteByQueryResponse.getIndices().size(), equalTo(1));
for (IndexDeleteByQueryResponse indexDeleteByQueryResponse : deleteByQueryResponse) {
assertThat(indexDeleteByQueryResponse.getIndex(), equalTo("test"));
assertThat(indexDeleteByQueryResponse.getShardInfo().getFailures().length, equalTo(0));
}
refresh();
searchResponse = client().prepareSearch("test").get();
assertNoFailures(searchResponse);
assertThat(searchResponse.getHits().totalHits(), equalTo(1l));
}
private static String indexOrAlias() {
return randomBoolean() ? "test" : "alias";
}
private void assertSyncShardInfo(ActionWriteResponse.ShardInfo shardInfo, NumShards numShards) {
assertThat(shardInfo.getTotal(), greaterThanOrEqualTo(numShards.totalNumShards));
// we do not ensure green so just make sure request succeeded at least on all primaries
assertThat(shardInfo.getSuccessful(), greaterThanOrEqualTo(numShards.numPrimaries));
assertThat(shardInfo.getFailed(), equalTo(0));
for (ActionWriteResponse.ShardInfo.Failure failure : shardInfo.getFailures()) {
assertThat(failure.status(), equalTo(RestStatus.OK));
}
}
}

View File

@ -28,7 +28,6 @@ import org.elasticsearch.action.admin.indices.refresh.RefreshResponse;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.count.CountResponse;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.deletebyquery.DeleteByQueryResponse;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.common.xcontent.XContentBuilder;
@ -177,23 +176,6 @@ public class DocumentActionsTests extends ElasticsearchIntegrationTest {
assertThat(countResponse.getSuccessfulShards(), equalTo(numShards.numPrimaries));
assertThat(countResponse.getFailedShards(), equalTo(0));
}
logger.info("Delete by query");
DeleteByQueryResponse queryResponse = client().prepareDeleteByQuery().setIndices("test").setQuery(termQuery("name", "test2")).execute().actionGet();
assertThat(queryResponse.getIndex(getConcreteIndexName()).getShardInfo().getTotal(), greaterThanOrEqualTo(numShards.totalNumShards));
assertThat(queryResponse.getIndex(getConcreteIndexName()).getShardInfo().getSuccessful(), greaterThanOrEqualTo(numShards.totalNumShards));
assertThat(queryResponse.getIndex(getConcreteIndexName()).getShardInfo().getFailures().length, equalTo(0));
client().admin().indices().refresh(refreshRequest("test")).actionGet();
logger.info("Get [type1/1] and [type1/2], should be empty");
for (int i = 0; i < 5; i++) {
getResult = client().get(getRequest("test").type("type1").id("1")).actionGet();
assertThat(getResult.getIndex(), equalTo(getConcreteIndexName()));
assertThat("cycle #" + i, getResult.getSourceAsString(), equalTo(source("1", "test").string()));
getResult = client().get(getRequest("test").type("type1").id("2")).actionGet();
assertThat("cycle #" + i, getResult.isExists(), equalTo(false));
assertThat(getResult.getIndex(), equalTo(getConcreteIndexName()));
}
}
@Test

View File

@ -26,7 +26,6 @@ import org.elasticsearch.action.bulk.BulkItemResponse;
import org.elasticsearch.action.bulk.BulkRequestBuilder;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.deletebyquery.IndexDeleteByQueryResponse;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.cluster.ClusterState;
@ -100,17 +99,6 @@ public class ShardInfoTests extends ElasticsearchIntegrationTest {
}
}
@Test
public void testDeleteByQuery() throws Exception {
int numPrimaryShards = randomIntBetween(1, 2);
prepareIndex(numPrimaryShards);
IndexDeleteByQueryResponse indexDeleteByQueryResponse = client().prepareDeleteByQuery("idx")
.setQuery(QueryBuilders.matchAllQuery())
.get().getIndex("idx");
assertShardInfo(indexDeleteByQueryResponse, numCopies * numPrimaryShards, numNodes * numPrimaryShards);
}
private void prepareIndex(int numberOfPrimaryShards) throws Exception {
prepareIndex(numberOfPrimaryShards, false);
}

View File

@ -39,7 +39,6 @@ import org.elasticsearch.action.admin.indices.stats.IndicesStatsRequestBuilder;
import org.elasticsearch.action.admin.indices.validate.query.ValidateQueryRequestBuilder;
import org.elasticsearch.action.admin.indices.warmer.get.GetWarmersRequestBuilder;
import org.elasticsearch.action.count.CountRequestBuilder;
import org.elasticsearch.action.deletebyquery.DeleteByQueryRequestBuilder;
import org.elasticsearch.action.percolate.MultiPercolateRequestBuilder;
import org.elasticsearch.action.percolate.PercolateRequestBuilder;
import org.elasticsearch.action.percolate.PercolateSourceBuilder;
@ -85,7 +84,6 @@ public class IndicesOptionsIntegrationTests extends ElasticsearchIntegrationTest
verify(validateQuery("test1", "test2"), true);
verify(aliasExists("test1", "test2"), true);
verify(typesExists("test1", "test2"), true);
verify(deleteByQuery("test1", "test2"), true);
verify(percolate("test1", "test2"), true);
verify(mpercolate(null, "test1", "test2"), false);
verify(suggest("test1", "test2"), true);
@ -108,7 +106,6 @@ public class IndicesOptionsIntegrationTests extends ElasticsearchIntegrationTest
verify(validateQuery("test1", "test2").setIndicesOptions(options), true);
verify(aliasExists("test1", "test2").setIndicesOptions(options), true);
verify(typesExists("test1", "test2").setIndicesOptions(options), true);
verify(deleteByQuery("test1", "test2").setIndicesOptions(options), true);
verify(percolate("test1", "test2").setIndicesOptions(options), true);
verify(mpercolate(options, "test1", "test2").setIndicesOptions(options), false);
verify(suggest("test1", "test2").setIndicesOptions(options), true);
@ -131,7 +128,6 @@ public class IndicesOptionsIntegrationTests extends ElasticsearchIntegrationTest
verify(validateQuery("test1", "test2").setIndicesOptions(options), false);
verify(aliasExists("test1", "test2").setIndicesOptions(options), false);
verify(typesExists("test1", "test2").setIndicesOptions(options), false);
verify(deleteByQuery("test1", "test2").setIndicesOptions(options), false);
verify(percolate("test1", "test2").setIndicesOptions(options), false);
verify(mpercolate(options, "test1", "test2").setIndicesOptions(options), false);
verify(suggest("test1", "test2").setIndicesOptions(options), false);
@ -156,7 +152,6 @@ public class IndicesOptionsIntegrationTests extends ElasticsearchIntegrationTest
verify(validateQuery("test1", "test2").setIndicesOptions(options), false);
verify(aliasExists("test1", "test2").setIndicesOptions(options), false);
verify(typesExists("test1", "test2").setIndicesOptions(options), false);
verify(deleteByQuery("test1", "test2").setIndicesOptions(options), false);
verify(percolate("test1", "test2").setIndicesOptions(options), false);
verify(mpercolate(options, "test1", "test2").setIndicesOptions(options), false);
verify(suggest("test1", "test2").setIndicesOptions(options), false);
@ -190,7 +185,6 @@ public class IndicesOptionsIntegrationTests extends ElasticsearchIntegrationTest
verify(validateQuery("test1").setIndicesOptions(options), true);
verify(aliasExists("test1").setIndicesOptions(options), true);
verify(typesExists("test1").setIndicesOptions(options), true);
verify(deleteByQuery("test1").setIndicesOptions(options), true);
verify(percolate("test1").setIndicesOptions(options), true);
verify(mpercolate(options, "test1").setIndicesOptions(options), true);
verify(suggest("test1").setIndicesOptions(options), true);
@ -213,7 +207,6 @@ public class IndicesOptionsIntegrationTests extends ElasticsearchIntegrationTest
verify(validateQuery("test1").setIndicesOptions(options), false);
verify(aliasExists("test1").setIndicesOptions(options), false);
verify(typesExists("test1").setIndicesOptions(options), false);
verify(deleteByQuery("test1").setIndicesOptions(options), false);
verify(percolate("test1").setIndicesOptions(options), false);
verify(mpercolate(options, "test1").setIndicesOptions(options), false);
verify(suggest("test1").setIndicesOptions(options), false);
@ -239,7 +232,6 @@ public class IndicesOptionsIntegrationTests extends ElasticsearchIntegrationTest
verify(validateQuery("test1").setIndicesOptions(options), false);
verify(aliasExists("test1").setIndicesOptions(options), false);
verify(typesExists("test1").setIndicesOptions(options), false);
verify(deleteByQuery("test1").setIndicesOptions(options), false);
verify(percolate("test1").setIndicesOptions(options), false);
verify(mpercolate(options, "test1").setIndicesOptions(options), false);
verify(suggest("test1").setIndicesOptions(options), false);
@ -265,7 +257,6 @@ public class IndicesOptionsIntegrationTests extends ElasticsearchIntegrationTest
verify(validateQuery("test1").setIndicesOptions(options), true);
verify(aliasExists("test1").setIndicesOptions(options), true);
verify(typesExists("test1").setIndicesOptions(options), true);
verify(deleteByQuery("test1").setIndicesOptions(options), true);
verify(percolate("test1").setIndicesOptions(options), true);
verify(suggest("test1").setIndicesOptions(options), true);
verify(getAliases("test1").setIndicesOptions(options), true);
@ -287,7 +278,6 @@ public class IndicesOptionsIntegrationTests extends ElasticsearchIntegrationTest
verify(validateQuery("test1").setIndicesOptions(options), false);
verify(aliasExists("test1").setIndicesOptions(options), false);
verify(typesExists("test1").setIndicesOptions(options), false);
verify(deleteByQuery("test1").setIndicesOptions(options), false);
verify(percolate("test1").setIndicesOptions(options), false);
verify(suggest("test1").setIndicesOptions(options), false);
verify(getAliases("test1").setIndicesOptions(options), false);
@ -312,7 +302,6 @@ public class IndicesOptionsIntegrationTests extends ElasticsearchIntegrationTest
verify(validateQuery("test1").setIndicesOptions(options), false);
verify(aliasExists("test1").setIndicesOptions(options), false);
verify(typesExists("test1").setIndicesOptions(options), false);
verify(deleteByQuery("test1").setIndicesOptions(options), false);
verify(percolate("test1").setIndicesOptions(options), false);
verify(suggest("test1").setIndicesOptions(options), false);
verify(getAliases("test1").setIndicesOptions(options), false);
@ -369,7 +358,6 @@ public class IndicesOptionsIntegrationTests extends ElasticsearchIntegrationTest
verify(validateQuery(indices), true);
verify(aliasExists(indices), false);
verify(typesExists(indices), false);
verify(deleteByQuery(indices), true);
verify(percolate(indices), false);
verify(mpercolate(null, indices), false);
verify(suggest(indices), false);
@ -393,7 +381,6 @@ public class IndicesOptionsIntegrationTests extends ElasticsearchIntegrationTest
verify(validateQuery(indices).setIndicesOptions(options), false);
verify(aliasExists(indices).setIndicesOptions(options), false);
verify(typesExists(indices).setIndicesOptions(options), false);
verify(deleteByQuery(indices).setIndicesOptions(options), false);
verify(percolate(indices).setIndicesOptions(options), false);
verify(mpercolate(options, indices), false);
verify(suggest(indices).setIndicesOptions(options), false);
@ -420,7 +407,6 @@ public class IndicesOptionsIntegrationTests extends ElasticsearchIntegrationTest
verify(validateQuery(indices), false);
verify(aliasExists(indices), false);
verify(typesExists(indices), false);
verify(deleteByQuery(indices), false);
verify(percolate(indices), false);
verify(mpercolate(null, indices), false);
verify(suggest(indices), false);
@ -444,7 +430,6 @@ public class IndicesOptionsIntegrationTests extends ElasticsearchIntegrationTest
verify(validateQuery(indices), true);
verify(aliasExists(indices), false);
verify(typesExists(indices), false);
verify(deleteByQuery(indices), true);
verify(percolate(indices), false);
verify(mpercolate(null, indices), false);
verify(suggest(indices), false);
@ -468,7 +453,6 @@ public class IndicesOptionsIntegrationTests extends ElasticsearchIntegrationTest
verify(validateQuery(indices).setIndicesOptions(options), false);
verify(aliasExists(indices).setIndicesOptions(options), false);
verify(typesExists(indices).setIndicesOptions(options), false);
verify(deleteByQuery(indices).setIndicesOptions(options), false);
verify(percolate(indices).setIndicesOptions(options), false);
verify(mpercolate(options, indices), false);
verify(suggest(indices).setIndicesOptions(options), false);
@ -848,10 +832,6 @@ public class IndicesOptionsIntegrationTests extends ElasticsearchIntegrationTest
return client().admin().indices().prepareTypesExists(indices).setTypes("dummy");
}
private static DeleteByQueryRequestBuilder deleteByQuery(String... indices) {
return client().prepareDeleteByQuery(indices).setQuery(boolQuery().mustNot(matchAllQuery()));
}
private static PercolateRequestBuilder percolate(String... indices) {
return client().preparePercolate().setIndices(indices)
.setSource(new PercolateSourceBuilder().setDoc(docBuilder().setDoc("k", "v")))

View File

@ -256,113 +256,6 @@ public class SimpleNestedTests extends ElasticsearchIntegrationTest {
}
}
@Test
public void simpleNestedDeletedByQuery1() throws Exception {
simpleNestedDeleteByQuery(3, 0);
}
@Test
public void simpleNestedDeletedByQuery2() throws Exception {
simpleNestedDeleteByQuery(3, 1);
}
@Test
public void simpleNestedDeletedByQuery3() throws Exception {
simpleNestedDeleteByQuery(3, 2);
}
private void simpleNestedDeleteByQuery(int total, int docToDelete) throws Exception {
assertAcked(prepareCreate("test")
.setSettings(settingsBuilder().put(indexSettings()).put("index.referesh_interval", -1).build())
.addMapping("type1", jsonBuilder().startObject().startObject("type1").startObject("properties")
.startObject("nested1")
.field("type", "nested")
.endObject()
.endObject().endObject().endObject()));
ensureGreen();
for (int i = 0; i < total; i++) {
client().prepareIndex("test", "type1", Integer.toString(i)).setSource(jsonBuilder().startObject()
.field("field1", "value1")
.startArray("nested1")
.startObject()
.field("n_field1", "n_value1_1")
.field("n_field2", "n_value2_1")
.endObject()
.startObject()
.field("n_field1", "n_value1_2")
.field("n_field2", "n_value2_2")
.endObject()
.endArray()
.endObject()).execute().actionGet();
}
flush();
assertDocumentCount("test", total * 3);
client().prepareDeleteByQuery("test").setQuery(QueryBuilders.idsQuery("type1").ids(Integer.toString(docToDelete))).execute().actionGet();
flush();
refresh();
assertDocumentCount("test", (total * 3l) - 3);
for (int i = 0; i < total; i++) {
assertThat(client().prepareGet("test", "type1", Integer.toString(i)).execute().actionGet().isExists(), equalTo(i != docToDelete));
}
}
@Test
public void noChildrenNestedDeletedByQuery1() throws Exception {
noChildrenNestedDeleteByQuery(3, 0);
}
@Test
public void noChildrenNestedDeletedByQuery2() throws Exception {
noChildrenNestedDeleteByQuery(3, 1);
}
@Test
public void noChildrenNestedDeletedByQuery3() throws Exception {
noChildrenNestedDeleteByQuery(3, 2);
}
private void noChildrenNestedDeleteByQuery(long total, int docToDelete) throws Exception {
assertAcked(prepareCreate("test")
.setSettings(settingsBuilder().put(indexSettings()).put("index.referesh_interval", -1).build())
.addMapping("type1", jsonBuilder().startObject().startObject("type1").startObject("properties")
.startObject("nested1")
.field("type", "nested")
.endObject()
.endObject().endObject().endObject()));
ensureGreen();
for (int i = 0; i < total; i++) {
client().prepareIndex("test", "type1", Integer.toString(i)).setSource(jsonBuilder().startObject()
.field("field1", "value1")
.endObject()).execute().actionGet();
}
flush();
refresh();
assertDocumentCount("test", total);
client().prepareDeleteByQuery("test").setQuery(QueryBuilders.idsQuery("type1").ids(Integer.toString(docToDelete))).execute().actionGet();
flush();
refresh();
assertDocumentCount("test", total - 1);
for (int i = 0; i < total; i++) {
assertThat(client().prepareGet("test", "type1", Integer.toString(i)).execute().actionGet().isExists(), equalTo(i != docToDelete));
}
}
@Test
public void multiNested() throws Exception {
assertAcked(prepareCreate("test")
@ -487,15 +380,6 @@ public class SimpleNestedTests extends ElasticsearchIntegrationTest {
flush();
refresh();
assertDocumentCount("test", 6);
client().prepareDeleteByQuery("alias1").setQuery(QueryBuilders.matchAllQuery()).execute().actionGet();
flush();
refresh();
// This must be 3, otherwise child docs aren't deleted.
// If this is 5 then only the parent has been removed
assertDocumentCount("test", 3);
assertThat(client().prepareGet("test", "type1", "1").execute().actionGet().isExists(), equalTo(false));
}
@Test
@ -1371,4 +1255,4 @@ public class SimpleNestedTests extends ElasticsearchIntegrationTest {
}
}
}

View File

@ -110,40 +110,6 @@ public class DestructiveOperationsIntegrationTests extends ElasticsearchIntegrat
// end close index:
client().admin().indices().prepareDelete("_all").get();
// delete_by_query:
settings = ImmutableSettings.builder()
.put(DestructiveOperations.REQUIRES_NAME, true)
.build();
assertAcked(client().admin().cluster().prepareUpdateSettings().setTransientSettings(settings));
assertAcked(client().admin().indices().prepareCreate("index1").get());
assertAcked(client().admin().indices().prepareCreate("1index").get());
// Should succeed, since no wildcards
client().prepareDeleteByQuery("1index").setQuery(QueryBuilders.matchAllQuery()).get();
try {
client().prepareDeleteByQuery("_all").setQuery(QueryBuilders.matchAllQuery()).get();
fail();
} catch (ElasticsearchIllegalArgumentException e) {}
try {
client().prepareDeleteByQuery().setQuery(QueryBuilders.matchAllQuery()).get();
fail();
} catch (ElasticsearchIllegalArgumentException e) {}
settings = ImmutableSettings.builder()
.put(DestructiveOperations.REQUIRES_NAME, false)
.build();
assertAcked(client().admin().cluster().prepareUpdateSettings().setTransientSettings(settings));
client().prepareDeleteByQuery().setQuery(QueryBuilders.matchAllQuery()).get();
client().prepareDeleteByQuery("_all").setQuery(QueryBuilders.matchAllQuery()).get();
assertAcked(client().admin().cluster().prepareUpdateSettings().setTransientSettings(settings));
client().prepareDeleteByQuery().setQuery(QueryBuilders.matchAllQuery()).get();
// end delete_by_query:
client().admin().indices().prepareDelete("_all").get();
}
}

View File

@ -102,24 +102,6 @@ public class AliasRoutingTests extends ElasticsearchIntegrationTest {
assertThat(client().prepareGet("test", "type1", "1").setRouting("0").execute().actionGet().isExists(), equalTo(true));
assertThat(client().prepareGet("alias0", "type1", "1").execute().actionGet().isExists(), equalTo(true));
}
logger.info("--> deleting_by_query with 1 as routing, should not delete anything");
client().prepareDeleteByQuery().setQuery(matchAllQuery()).setRouting("1").execute().actionGet();
refresh();
for (int i = 0; i < 5; i++) {
assertThat(client().prepareGet("test", "type1", "1").execute().actionGet().isExists(), equalTo(false));
assertThat(client().prepareGet("test", "type1", "1").setRouting("0").execute().actionGet().isExists(), equalTo(true));
assertThat(client().prepareGet("alias0", "type1", "1").execute().actionGet().isExists(), equalTo(true));
}
logger.info("--> deleting_by_query with alias0, should delete");
client().prepareDeleteByQuery("alias0").setQuery(matchAllQuery()).execute().actionGet();
refresh();
for (int i = 0; i < 5; i++) {
assertThat(client().prepareGet("test", "type1", "1").execute().actionGet().isExists(), equalTo(false));
assertThat(client().prepareGet("test", "type1", "1").setRouting("0").execute().actionGet().isExists(), equalTo(false));
assertThat(client().prepareGet("alias0", "type1", "1").execute().actionGet().isExists(), equalTo(false));
}
}
@Test

View File

@ -87,22 +87,6 @@ public class SimpleRoutingTests extends ElasticsearchIntegrationTest {
for (int i = 0; i < 5; i++) {
assertThat(client().prepareGet("test", "type1", "1").setRouting("0").execute().actionGet().isExists(), equalTo(true));
}
logger.info("--> deleting_by_query with 1 as routing, should not delete anything");
client().prepareDeleteByQuery().setQuery(matchAllQuery()).setRouting("1").execute().actionGet();
client().admin().indices().prepareRefresh().execute().actionGet();
for (int i = 0; i < 5; i++) {
assertThat(client().prepareGet("test", "type1", "1").execute().actionGet().isExists(), equalTo(false));
assertThat(client().prepareGet("test", "type1", "1").setRouting("0").execute().actionGet().isExists(), equalTo(true));
}
logger.info("--> deleting_by_query with , should delete");
client().prepareDeleteByQuery().setQuery(matchAllQuery()).setRouting("0").execute().actionGet();
client().admin().indices().prepareRefresh().execute().actionGet();
for (int i = 0; i < 5; i++) {
assertThat(client().prepareGet("test", "type1", "1").execute().actionGet().isExists(), equalTo(false));
assertThat(client().prepareGet("test", "type1", "1").setRouting("0").execute().actionGet().isExists(), equalTo(false));
}
}
public void testSimpleSearchRouting() {

View File

@ -26,7 +26,6 @@ import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsResponse;
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingResponse;
import org.elasticsearch.action.admin.indices.stats.IndicesStatsResponse;
import org.elasticsearch.action.count.CountResponse;
import org.elasticsearch.action.deletebyquery.DeleteByQueryResponse;
import org.elasticsearch.action.explain.ExplainResponse;
import org.elasticsearch.action.index.IndexRequestBuilder;
import org.elasticsearch.action.search.SearchPhaseExecutionException;
@ -1379,99 +1378,6 @@ public class SimpleChildQuerySearchTests extends ElasticsearchIntegrationTest {
assertThat(searchResponse.getHits().totalHits(), equalTo(2l));
}
@Test
public void testDeleteByQuery_has_child() throws Exception {
assertAcked(prepareCreate("test")
.setSettings(
settingsBuilder().put(indexSettings())
.put("index.refresh_interval", "-1")
)
.addMapping("parent")
.addMapping("child", "_parent", "type=parent"));
ensureGreen();
// index simple data
client().prepareIndex("test", "parent", "p1").setSource("p_field", "p_value1").get();
client().prepareIndex("test", "child", "c1").setSource("c_field", "red").setParent("p1").get();
client().prepareIndex("test", "child", "c2").setSource("c_field", "yellow").setParent("p1").get();
client().prepareIndex("test", "parent", "p2").setSource("p_field", "p_value2").get();
client().admin().indices().prepareFlush("test").get();
client().prepareIndex("test", "child", "c3").setSource("c_field", "blue").setParent("p2").get();
client().prepareIndex("test", "child", "c4").setSource("c_field", "red").setParent("p2").get();
client().prepareIndex("test", "parent", "p3").setSource("p_field", "p_value3").get();
client().admin().indices().prepareFlush("test").get();
client().prepareIndex("test", "child", "c5").setSource("c_field", "blue").setParent("p3").get();
client().prepareIndex("test", "child", "c6").setSource("c_field", "red").setParent("p3").get();
client().admin().indices().prepareRefresh().get();
// p4 will not be found via search api, but will be deleted via delete_by_query api!
client().prepareIndex("test", "parent", "p4").setSource("p_field", "p_value4").get();
client().prepareIndex("test", "child", "c7").setSource("c_field", "blue").setParent("p4").get();
client().prepareIndex("test", "child", "c8").setSource("c_field", "red").setParent("p4").get();
SearchResponse searchResponse = client().prepareSearch("test")
.setQuery(randomHasChild("child", "c_field", "blue"))
.get();
assertHitCount(searchResponse, 2l);
// Delete by query doesn't support p/c queries. If the delete by query has a different execution mode
// that doesn't rely on IW#deleteByQuery() then this test can be changed.
DeleteByQueryResponse deleteByQueryResponse = client().prepareDeleteByQuery("test").setQuery(randomHasChild("child", "c_field", "blue")).get();
assertThat(deleteByQueryResponse.getIndex("test").getShardInfo().getSuccessful(), equalTo(0));
assertThat(deleteByQueryResponse.getIndex("test").getShardInfo().getFailures().length, equalTo(getNumShards("test").numPrimaries));
assertThat(deleteByQueryResponse.getIndex("test").getShardInfo().getFailures()[0].reason(), containsString("[has_child] query and filter unsupported in delete_by_query api"));
client().admin().indices().prepareRefresh("test").get();
searchResponse = client().prepareSearch("test")
.setQuery(randomHasChild("child", "c_field", "blue"))
.get();
assertHitCount(searchResponse, 3l);
}
@Test
public void testDeleteByQuery_has_child_SingleRefresh() throws Exception {
assertAcked(prepareCreate("test")
.setSettings(
settingsBuilder()
.put(indexSettings())
.put("index.refresh_interval", "-1")
)
.addMapping("parent")
.addMapping("child", "_parent", "type=parent"));
ensureGreen();
// index simple data
client().prepareIndex("test", "parent", "p1").setSource("p_field", "p_value1").get();
client().prepareIndex("test", "child", "c1").setSource("c_field", "red").setParent("p1").get();
client().prepareIndex("test", "child", "c2").setSource("c_field", "yellow").setParent("p1").get();
client().admin().indices().prepareFlush().get();
client().prepareIndex("test", "parent", "p2").setSource("p_field", "p_value2").get();
client().prepareIndex("test", "child", "c3").setSource("c_field", "blue").setParent("p2").get();
client().prepareIndex("test", "child", "c4").setSource("c_field", "red").setParent("p2").get();
client().prepareIndex("test", "parent", "p3").setSource("p_field", "p_value3").get();
client().prepareIndex("test", "child", "c5").setSource("c_field", "blue").setParent("p3").get();
client().prepareIndex("test", "child", "c6").setSource("c_field", "red").setParent("p3").get();
client().prepareIndex("test", "parent", "p4").setSource("p_field", "p_value4").get();
client().prepareIndex("test", "child", "c7").setSource("c_field", "blue").setParent("p4").get();
client().prepareIndex("test", "child", "c8").setSource("c_field", "red").setParent("p4").get();
client().admin().indices().prepareRefresh().get();
SearchResponse searchResponse = client().prepareSearch("test")
.setQuery(randomHasChild("child", "c_field", "blue"))
.get();
assertHitCount(searchResponse, 3l);
DeleteByQueryResponse deleteByQueryResponse = client().prepareDeleteByQuery("test").setQuery(randomHasChild("child", "c_field", "blue")).get();
assertThat(deleteByQueryResponse.getIndex("test").getShardInfo().getSuccessful(), equalTo(0));
assertThat(deleteByQueryResponse.getIndex("test").getShardInfo().getFailures().length, equalTo(getNumShards("test").numPrimaries));
assertThat(deleteByQueryResponse.getIndex("test").getShardInfo().getFailures()[0].reason(), containsString("[has_child] query and filter unsupported in delete_by_query api"));
client().admin().indices().prepareRefresh("test").get();
searchResponse = client().prepareSearch("test")
.setQuery(randomHasChild("child", "c_field", "blue"))
.get();
assertHitCount(searchResponse, 3l);
}
private QueryBuilder randomHasChild(String type, String field, String value) {
if (randomBoolean()) {
if (randomBoolean()) {
@ -1484,49 +1390,6 @@ public class SimpleChildQuerySearchTests extends ElasticsearchIntegrationTest {
}
}
@Test
public void testDeleteByQuery_has_parent() throws Exception {
assertAcked(prepareCreate("test")
.setSettings(
settingsBuilder()
.put(indexSettings())
.put("index.refresh_interval", "-1")
)
.addMapping("parent")
.addMapping("child", "_parent", "type=parent"));
ensureGreen();
// index simple data
client().prepareIndex("test", "parent", "p1").setSource("p_field", "p_value1").get();
client().prepareIndex("test", "child", "c1").setSource("c_field", "red").setParent("p1").get();
client().prepareIndex("test", "child", "c2").setSource("c_field", "yellow").setParent("p1").get();
client().prepareIndex("test", "parent", "p2").setSource("p_field", "p_value2").get();
client().admin().indices().prepareFlush("test").get();
client().prepareIndex("test", "child", "c3").setSource("c_field", "blue").setParent("p2").get();
client().prepareIndex("test", "child", "c4").setSource("c_field", "red").setParent("p2").get();
client().admin().indices().prepareRefresh().get();
SearchResponse searchResponse = client().prepareSearch("test")
.setQuery(randomHasParent("parent", "p_field", "p_value2"))
.get();
assertHitCount(searchResponse, 2l);
DeleteByQueryResponse deleteByQueryResponse = client().prepareDeleteByQuery("test")
.setQuery(randomHasParent("parent", "p_field", "p_value2"))
.get();
assertThat(deleteByQueryResponse.getIndex("test").getShardInfo().getSuccessful(), equalTo(0));
assertThat(deleteByQueryResponse.getIndex("test").getShardInfo().getFailures().length, equalTo(getNumShards("test").numPrimaries));
assertThat(deleteByQueryResponse.getIndex("test").getShardInfo().getFailures()[0].reason(), containsString("[has_parent] query and filter unsupported in delete_by_query api"));
client().admin().indices().prepareRefresh("test").get();
client().admin().indices().prepareRefresh("test").get();
client().admin().indices().prepareRefresh("test").get();
searchResponse = client().prepareSearch("test")
.setQuery(randomHasParent("parent", "p_field", "p_value2"))
.get();
assertHitCount(searchResponse, 2l);
}
private QueryBuilder randomHasParent(String type, String field, String value) {
if (randomBoolean()) {
if (randomBoolean()) {

View File

@ -63,7 +63,6 @@ public class Search1StressTest {
private int numberOfValues = 20;
private int numberOfHits = 300;
private TimeValue flusherThrottle = TimeValue.timeValueMillis(1000);
private TimeValue deleteByQueryThrottle = TimeValue.timeValueMillis(5000);
private Settings settings = ImmutableSettings.Builder.EMPTY_SETTINGS;
@ -130,11 +129,6 @@ public class Search1StressTest {
return this;
}
public Search1StressTest setDeleteByQueryThrottle(TimeValue deleteByQueryThrottle) {
this.deleteByQueryThrottle = deleteByQueryThrottle;
return this;
}
public Search1StressTest setSettings(Settings settings) {
this.settings = settings;
return this;
@ -264,28 +258,6 @@ public class Search1StressTest {
}
}
private class DeleteByQuery extends Thread {
volatile boolean close = false;
volatile boolean closed = false;
@Override
public void run() {
while (true) {
if (close) {
closed = true;
return;
}
try {
client.client().prepareDeleteByQuery().setQuery(termQuery("num", nextNumValue())).execute().actionGet();
Thread.sleep(deleteByQueryThrottle.millis());
} catch (Exception e) {
logger.warn("failed to delete_by_query", e);
}
}
}
}
private void indexDoc() throws Exception {
XContentBuilder json = XContentFactory.jsonBuilder().startObject()
.field("num", nextNumValue())
@ -340,13 +312,6 @@ public class Search1StressTest {
flusher.start();
}
DeleteByQuery deleteByQuery = null;
if (deleteByQueryThrottle.millis() > 0) {
deleteByQuery = new DeleteByQuery();
deleteByQuery.start();
}
long testStart = System.currentTimeMillis();
while (true) {
@ -362,10 +327,6 @@ public class Search1StressTest {
flusher.close = true;
}
if (deleteByQuery != null) {
deleteByQuery.close = true;
}
for (Searcher searcherThread : searcherThreads) {
searcherThread.close = true;
}
@ -379,9 +340,6 @@ public class Search1StressTest {
if (flusher != null && !flusher.closed) {
logger.warn("flusher not closed!");
}
if (deleteByQuery != null && !deleteByQuery.closed) {
logger.warn("deleteByQuery not closed!");
}
for (Searcher searcherThread : searcherThreads) {
if (!searcherThread.closed) {
logger.warn("search thread not closed!");
@ -410,7 +368,6 @@ public class Search1StressTest {
.setIndexerThrottle(TimeValue.timeValueMillis(100))
.setSearchers(10)
.setSearcherThrottle(TimeValue.timeValueMillis(10))
.setDeleteByQueryThrottle(TimeValue.timeValueMillis(-1))
.setFlusherThrottle(TimeValue.timeValueMillis(1000))
.setNumberOfIndices(10)
.setNumberOfTypes(5)