Skip to content

Commit

Permalink
Disabled parent/child queries in the delete by query api.
Browse files Browse the repository at this point in the history
It wasn't properly implemented and could lead to a shard being failed and not able to recover.

Closes #5828 #5916
  • Loading branch information
martijnvg committed Apr 28, 2014
1 parent 3226cd8 commit e0026e1
Show file tree
Hide file tree
Showing 10 changed files with 93 additions and 182 deletions.
Expand Up @@ -52,6 +52,8 @@
*/
public class TransportShardDeleteByQueryAction extends TransportShardReplicationOperationAction<ShardDeleteByQueryRequest, ShardDeleteByQueryRequest, ShardDeleteByQueryResponse> {

public final static String DELETE_BY_QUERY_API = "delete_by_query";

private final ScriptService scriptService;
private final CacheRecycler cacheRecycler;
private final PageCacheRecycler pageCacheRecycler;
Expand Down Expand Up @@ -116,7 +118,7 @@ protected PrimaryResponse<ShardDeleteByQueryResponse, ShardDeleteByQueryRequest>
IndexShard indexShard = indexService.shardSafe(shardRequest.shardId);

SearchContext.setCurrent(new DefaultSearchContext(0, new ShardSearchRequest().types(request.types()), null,
indexShard.acquireSearcher("delete_by_query"), indexService, indexShard, scriptService, cacheRecycler,
indexShard.acquireSearcher(DELETE_BY_QUERY_API), indexService, indexShard, scriptService, cacheRecycler,
pageCacheRecycler, bigArrays));
try {
Engine.DeleteByQuery deleteByQuery = indexShard.prepareDeleteByQuery(request.source(), request.filteringAliases(), request.types())
Expand All @@ -139,7 +141,7 @@ protected void shardOperationOnReplica(ReplicaOperationRequest shardRequest) {
IndexShard indexShard = indexService.shardSafe(shardRequest.shardId);

SearchContext.setCurrent(new DefaultSearchContext(0, new ShardSearchRequest().types(request.types()), null,
indexShard.acquireSearcher("delete_by_query", IndexShard.Mode.WRITE), indexService, indexShard, scriptService,
indexShard.acquireSearcher(DELETE_BY_QUERY_API, IndexShard.Mode.WRITE), indexService, indexShard, scriptService,
cacheRecycler, pageCacheRecycler, bigArrays));
try {
Engine.DeleteByQuery deleteByQuery = indexShard.prepareDeleteByQuery(request.source(), request.filteringAliases(), request.types())
Expand Down
Expand Up @@ -24,18 +24,18 @@
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.lucene.search.XFilteredQuery;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.query.support.XContentStructure;
import org.elasticsearch.index.fielddata.plain.ParentChildIndexFieldData;
import org.elasticsearch.index.mapper.DocumentMapper;
import org.elasticsearch.index.mapper.internal.ParentFieldMapper;
import org.elasticsearch.index.query.support.XContentStructure;
import org.elasticsearch.index.search.child.ChildrenConstantScoreQuery;
import org.elasticsearch.index.search.child.CustomQueryWrappingFilter;
import org.elasticsearch.index.search.child.DeleteByQueryWrappingFilter;
import org.elasticsearch.index.search.nested.NonNestedDocsFilter;
import org.elasticsearch.search.internal.SearchContext;

import java.io.IOException;

import static org.elasticsearch.index.query.QueryParserUtils.ensureNotDeleteByQuery;

/**
*
*/
Expand All @@ -54,6 +54,7 @@ public String[] names() {

@Override
public Filter parse(QueryParseContext parseContext) throws IOException, QueryParsingException {
ensureNotDeleteByQuery(NAME, parseContext);
XContentParser parser = parseContext.parser();

boolean queryFound = false;
Expand Down Expand Up @@ -149,12 +150,7 @@ public Filter parse(QueryParseContext parseContext) throws IOException, QueryPar
if (filterName != null) {
parseContext.addNamedFilter(filterName, new CustomQueryWrappingFilter(childrenConstantScoreQuery));
}

boolean deleteByQuery = "delete_by_query".equals(SearchContext.current().source());
if (deleteByQuery) {
return new DeleteByQueryWrappingFilter(childrenConstantScoreQuery);
} else {
return new CustomQueryWrappingFilter(childrenConstantScoreQuery);
}
return new CustomQueryWrappingFilter(childrenConstantScoreQuery);
}

}
Expand Up @@ -23,19 +23,22 @@
import org.apache.lucene.search.Query;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.lucene.search.XConstantScoreQuery;
import org.elasticsearch.common.lucene.search.XFilteredQuery;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.query.support.XContentStructure;
import org.elasticsearch.index.fielddata.plain.ParentChildIndexFieldData;
import org.elasticsearch.index.mapper.DocumentMapper;
import org.elasticsearch.index.mapper.internal.ParentFieldMapper;
import org.elasticsearch.index.search.child.*;
import org.elasticsearch.index.query.support.XContentStructure;
import org.elasticsearch.index.search.child.ChildrenConstantScoreQuery;
import org.elasticsearch.index.search.child.ChildrenQuery;
import org.elasticsearch.index.search.child.CustomQueryWrappingFilter;
import org.elasticsearch.index.search.child.ScoreType;
import org.elasticsearch.index.search.nested.NonNestedDocsFilter;
import org.elasticsearch.search.internal.SearchContext;

import java.io.IOException;

import static org.elasticsearch.index.query.QueryParserUtils.ensureNotDeleteByQuery;

/**
*
*/
Expand All @@ -54,6 +57,7 @@ public String[] names() {

@Override
public Query parse(QueryParseContext parseContext) throws IOException, QueryParsingException {
ensureNotDeleteByQuery(NAME, parseContext);
XContentParser parser = parseContext.parser();

boolean queryFound = false;
Expand Down Expand Up @@ -147,17 +151,13 @@ public Query parse(QueryParseContext parseContext) throws IOException, QueryPars
// wrap the query with type query
innerQuery = new XFilteredQuery(innerQuery, parseContext.cacheFilter(childDocMapper.typeFilter(), null));

boolean deleteByQuery = "delete_by_query".equals(SearchContext.current().source());
Query query;
Filter parentFilter = parseContext.cacheFilter(parentDocMapper.typeFilter(), null);
ParentChildIndexFieldData parentChildIndexFieldData = parseContext.fieldData().getForField(parentFieldMapper);
if (!deleteByQuery && scoreType != null) {
if (scoreType != null) {
query = new ChildrenQuery(parentChildIndexFieldData, parentType, childType, parentFilter, innerQuery, scoreType, shortCircuitParentDocSet, nonNestedDocsFilter);
} else {
query = new ChildrenConstantScoreQuery(parentChildIndexFieldData, innerQuery, parentType, childType, parentFilter, shortCircuitParentDocSet, nonNestedDocsFilter);
if (deleteByQuery) {
query = new XConstantScoreQuery(new DeleteByQueryWrappingFilter(query));
}
}
if (queryName != null) {
parseContext.addNamedFilter(queryName, new CustomQueryWrappingFilter(query));
Expand Down
Expand Up @@ -27,19 +27,19 @@
import org.elasticsearch.common.lucene.search.XBooleanFilter;
import org.elasticsearch.common.lucene.search.XFilteredQuery;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.query.support.XContentStructure;
import org.elasticsearch.index.fielddata.plain.ParentChildIndexFieldData;
import org.elasticsearch.index.mapper.DocumentMapper;
import org.elasticsearch.index.mapper.internal.ParentFieldMapper;
import org.elasticsearch.index.query.support.XContentStructure;
import org.elasticsearch.index.search.child.CustomQueryWrappingFilter;
import org.elasticsearch.index.search.child.DeleteByQueryWrappingFilter;
import org.elasticsearch.index.search.child.ParentConstantScoreQuery;
import org.elasticsearch.search.internal.SearchContext;

import java.io.IOException;
import java.util.HashSet;
import java.util.Set;

import static org.elasticsearch.index.query.QueryParserUtils.ensureNotDeleteByQuery;

/**
*
*/
Expand All @@ -58,6 +58,7 @@ public String[] names() {

@Override
public Filter parse(QueryParseContext parseContext) throws IOException, QueryParsingException {
ensureNotDeleteByQuery(NAME, parseContext);
XContentParser parser = parseContext.parser();

boolean queryFound = false;
Expand Down Expand Up @@ -165,13 +166,7 @@ public Filter parse(QueryParseContext parseContext) throws IOException, QueryPar
if (filterName != null) {
parseContext.addNamedFilter(filterName, new CustomQueryWrappingFilter(parentConstantScoreQuery));
}

boolean deleteByQuery = "delete_by_query".equals(SearchContext.current().source());
if (deleteByQuery) {
return new DeleteByQueryWrappingFilter(parentConstantScoreQuery);
} else {
return new CustomQueryWrappingFilter(parentConstantScoreQuery);
}
return new CustomQueryWrappingFilter(parentConstantScoreQuery);
}

}
Expand Up @@ -25,23 +25,22 @@
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.lucene.search.NotFilter;
import org.elasticsearch.common.lucene.search.XBooleanFilter;
import org.elasticsearch.common.lucene.search.XConstantScoreQuery;
import org.elasticsearch.common.lucene.search.XFilteredQuery;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.query.support.XContentStructure;
import org.elasticsearch.index.fielddata.plain.ParentChildIndexFieldData;
import org.elasticsearch.index.mapper.DocumentMapper;
import org.elasticsearch.index.mapper.internal.ParentFieldMapper;
import org.elasticsearch.index.query.support.XContentStructure;
import org.elasticsearch.index.search.child.CustomQueryWrappingFilter;
import org.elasticsearch.index.search.child.DeleteByQueryWrappingFilter;
import org.elasticsearch.index.search.child.ParentConstantScoreQuery;
import org.elasticsearch.index.search.child.ParentQuery;
import org.elasticsearch.search.internal.SearchContext;

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";
Expand All @@ -57,6 +56,7 @@ public String[] names() {

@Override
public Query parse(QueryParseContext parseContext) throws IOException, QueryParsingException {
ensureNotDeleteByQuery(NAME, parseContext);
XContentParser parser = parseContext.parser();

boolean queryFound = false;
Expand Down Expand Up @@ -165,15 +165,11 @@ public Query parse(QueryParseContext parseContext) throws IOException, QueryPars
}
Filter childrenFilter = parseContext.cacheFilter(new NotFilter(parentFilter), null);

boolean deleteByQuery = "delete_by_query".equals(SearchContext.current().source());
Query query;
if (!deleteByQuery && score) {
if (score) {
query = new ParentQuery(parentChildIndexFieldData, innerQuery, parentType, childrenFilter);
} else {
query = new ParentConstantScoreQuery(parentChildIndexFieldData, innerQuery, parentType, childrenFilter);
if (deleteByQuery) {
query = new XConstantScoreQuery(new DeleteByQueryWrappingFilter(query));
}
}
query.setBoost(boost);
if (queryName != null) {
Expand Down
41 changes: 41 additions & 0 deletions src/main/java/org/elasticsearch/index/query/QueryParserUtils.java
@@ -0,0 +1,41 @@
/*
* 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) {
if (TransportShardDeleteByQueryAction.DELETE_BY_QUERY_API.equals(SearchContext.current().source())) {
throw new QueryParsingException(parseContext.index(), "[" + name + "] unsupported in delete_by_query api");
}
}

}
Expand Up @@ -24,18 +24,19 @@
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.lucene.search.XFilteredQuery;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.query.support.XContentStructure;
import org.elasticsearch.index.fielddata.plain.ParentChildIndexFieldData;
import org.elasticsearch.index.mapper.DocumentMapper;
import org.elasticsearch.index.mapper.internal.ParentFieldMapper;
import org.elasticsearch.index.query.support.XContentStructure;
import org.elasticsearch.index.search.child.CustomQueryWrappingFilter;
import org.elasticsearch.index.search.child.ScoreType;
import org.elasticsearch.index.search.child.TopChildrenQuery;
import org.elasticsearch.index.search.nested.NonNestedDocsFilter;
import org.elasticsearch.search.internal.SearchContext;

import java.io.IOException;

import static org.elasticsearch.index.query.QueryParserUtils.ensureNotDeleteByQuery;

/**
*
*/
Expand All @@ -54,6 +55,7 @@ public String[] names() {

@Override
public Query parse(QueryParseContext parseContext) throws IOException, QueryParsingException {
ensureNotDeleteByQuery(NAME, parseContext);
XContentParser parser = parseContext.parser();

boolean queryFound = false;
Expand Down Expand Up @@ -116,10 +118,6 @@ public Query parse(QueryParseContext parseContext) throws IOException, QueryPars
return null;
}

if ("delete_by_query".equals(SearchContext.current().source())) {
throw new QueryParsingException(parseContext.index(), "[top_children] unsupported in delete_by_query api");
}

DocumentMapper childDocMapper = parseContext.mapperService().documentMapper(childType);
if (childDocMapper == null) {
throw new QueryParsingException(parseContext.index(), "No mapping for for type [" + childType + "]");
Expand Down

0 comments on commit e0026e1

Please sign in to comment.