Fixed named filter and query support for the top_children, has_child and has_parent queries and filters.
Closes #4534
This commit is contained in:
parent
9c67be5181
commit
27b53b8edf
|
@ -144,7 +144,7 @@ public class HasChildFilterParser implements FilterParser {
|
||||||
Query childrenConstantScoreQuery = new ChildrenConstantScoreQuery(query, parentType, childType, parentFilter, shortCircuitParentDocSet, nonNestedDocsFilter);
|
Query childrenConstantScoreQuery = new ChildrenConstantScoreQuery(query, parentType, childType, parentFilter, shortCircuitParentDocSet, nonNestedDocsFilter);
|
||||||
|
|
||||||
if (filterName != null) {
|
if (filterName != null) {
|
||||||
parseContext.addNamedQuery(filterName, childrenConstantScoreQuery);
|
parseContext.addNamedFilter(filterName, new CustomQueryWrappingFilter(childrenConstantScoreQuery));
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean deleteByQuery = "delete_by_query".equals(SearchContext.current().source());
|
boolean deleteByQuery = "delete_by_query".equals(SearchContext.current().source());
|
||||||
|
|
|
@ -27,10 +27,7 @@ import org.elasticsearch.common.lucene.search.XConstantScoreQuery;
|
||||||
import org.elasticsearch.common.lucene.search.XFilteredQuery;
|
import org.elasticsearch.common.lucene.search.XFilteredQuery;
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
import org.elasticsearch.index.mapper.DocumentMapper;
|
import org.elasticsearch.index.mapper.DocumentMapper;
|
||||||
import org.elasticsearch.index.search.child.ChildrenConstantScoreQuery;
|
import org.elasticsearch.index.search.child.*;
|
||||||
import org.elasticsearch.index.search.child.ChildrenQuery;
|
|
||||||
import org.elasticsearch.index.search.child.DeleteByQueryWrappingFilter;
|
|
||||||
import org.elasticsearch.index.search.child.ScoreType;
|
|
||||||
import org.elasticsearch.index.search.nested.NonNestedDocsFilter;
|
import org.elasticsearch.index.search.nested.NonNestedDocsFilter;
|
||||||
import org.elasticsearch.search.internal.SearchContext;
|
import org.elasticsearch.search.internal.SearchContext;
|
||||||
|
|
||||||
|
@ -154,7 +151,7 @@ public class HasChildQueryParser implements QueryParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (queryName != null) {
|
if (queryName != null) {
|
||||||
parseContext.addNamedQuery(queryName, query);
|
parseContext.addNamedFilter(queryName, new CustomQueryWrappingFilter(query));
|
||||||
}
|
}
|
||||||
query.setBoost(boost);
|
query.setBoost(boost);
|
||||||
return query;
|
return query;
|
||||||
|
|
|
@ -161,7 +161,7 @@ public class HasParentFilterParser implements FilterParser {
|
||||||
Query parentConstantScoreQuery = new ParentConstantScoreQuery(query, parentType, childrenFilter);
|
Query parentConstantScoreQuery = new ParentConstantScoreQuery(query, parentType, childrenFilter);
|
||||||
|
|
||||||
if (filterName != null) {
|
if (filterName != null) {
|
||||||
parseContext.addNamedQuery(filterName, parentConstantScoreQuery);
|
parseContext.addNamedFilter(filterName, new CustomQueryWrappingFilter(parentConstantScoreQuery));
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean deleteByQuery = "delete_by_query".equals(SearchContext.current().source());
|
boolean deleteByQuery = "delete_by_query".equals(SearchContext.current().source());
|
||||||
|
|
|
@ -31,6 +31,7 @@ import org.elasticsearch.common.lucene.search.XFilteredQuery;
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
import org.elasticsearch.index.mapper.DocumentMapper;
|
import org.elasticsearch.index.mapper.DocumentMapper;
|
||||||
import org.elasticsearch.index.mapper.internal.ParentFieldMapper;
|
import org.elasticsearch.index.mapper.internal.ParentFieldMapper;
|
||||||
|
import org.elasticsearch.index.search.child.CustomQueryWrappingFilter;
|
||||||
import org.elasticsearch.index.search.child.DeleteByQueryWrappingFilter;
|
import org.elasticsearch.index.search.child.DeleteByQueryWrappingFilter;
|
||||||
import org.elasticsearch.index.search.child.ParentConstantScoreQuery;
|
import org.elasticsearch.index.search.child.ParentConstantScoreQuery;
|
||||||
import org.elasticsearch.index.search.child.ParentQuery;
|
import org.elasticsearch.index.search.child.ParentQuery;
|
||||||
|
@ -170,7 +171,7 @@ public class HasParentQueryParser implements QueryParser {
|
||||||
}
|
}
|
||||||
query.setBoost(boost);
|
query.setBoost(boost);
|
||||||
if (queryName != null) {
|
if (queryName != null) {
|
||||||
parseContext.addNamedQuery(queryName, query);
|
parseContext.addNamedFilter(queryName, new CustomQueryWrappingFilter(query));
|
||||||
}
|
}
|
||||||
return query;
|
return query;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ import org.elasticsearch.common.inject.Inject;
|
||||||
import org.elasticsearch.common.lucene.search.XFilteredQuery;
|
import org.elasticsearch.common.lucene.search.XFilteredQuery;
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
import org.elasticsearch.index.mapper.DocumentMapper;
|
import org.elasticsearch.index.mapper.DocumentMapper;
|
||||||
|
import org.elasticsearch.index.search.child.CustomQueryWrappingFilter;
|
||||||
import org.elasticsearch.index.search.child.ScoreType;
|
import org.elasticsearch.index.search.child.ScoreType;
|
||||||
import org.elasticsearch.index.search.child.TopChildrenQuery;
|
import org.elasticsearch.index.search.child.TopChildrenQuery;
|
||||||
import org.elasticsearch.search.internal.SearchContext;
|
import org.elasticsearch.search.internal.SearchContext;
|
||||||
|
@ -51,7 +52,7 @@ public class TopChildrenQueryParser implements QueryParser {
|
||||||
public Query parse(QueryParseContext parseContext) throws IOException, QueryParsingException {
|
public Query parse(QueryParseContext parseContext) throws IOException, QueryParsingException {
|
||||||
XContentParser parser = parseContext.parser();
|
XContentParser parser = parseContext.parser();
|
||||||
|
|
||||||
Query query = null;
|
Query innerQuery = null;
|
||||||
boolean queryFound = false;
|
boolean queryFound = false;
|
||||||
float boost = 1.0f;
|
float boost = 1.0f;
|
||||||
String childType = null;
|
String childType = null;
|
||||||
|
@ -72,7 +73,7 @@ public class TopChildrenQueryParser implements QueryParser {
|
||||||
// since we switch types, make sure we change the context
|
// since we switch types, make sure we change the context
|
||||||
String[] origTypes = QueryParseContext.setTypesWithPrevious(childType == null ? null : new String[]{childType});
|
String[] origTypes = QueryParseContext.setTypesWithPrevious(childType == null ? null : new String[]{childType});
|
||||||
try {
|
try {
|
||||||
query = parseContext.parseInnerQuery();
|
innerQuery = parseContext.parseInnerQuery();
|
||||||
} finally {
|
} finally {
|
||||||
QueryParseContext.setTypes(origTypes);
|
QueryParseContext.setTypes(origTypes);
|
||||||
}
|
}
|
||||||
|
@ -108,7 +109,7 @@ public class TopChildrenQueryParser implements QueryParser {
|
||||||
throw new QueryParsingException(parseContext.index(), "[top_children] requires 'type' field");
|
throw new QueryParsingException(parseContext.index(), "[top_children] requires 'type' field");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (query == null) {
|
if (innerQuery == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,13 +126,13 @@ public class TopChildrenQueryParser implements QueryParser {
|
||||||
}
|
}
|
||||||
String parentType = childDocMapper.parentFieldMapper().type();
|
String parentType = childDocMapper.parentFieldMapper().type();
|
||||||
|
|
||||||
query.setBoost(boost);
|
innerQuery.setBoost(boost);
|
||||||
// wrap the query with type query
|
// wrap the query with type query
|
||||||
query = new XFilteredQuery(query, parseContext.cacheFilter(childDocMapper.typeFilter(), null));
|
innerQuery = new XFilteredQuery(innerQuery, parseContext.cacheFilter(childDocMapper.typeFilter(), null));
|
||||||
TopChildrenQuery childQuery = new TopChildrenQuery(query, childType, parentType, scoreType, factor, incrementalFactor, parseContext.cacheRecycler());
|
TopChildrenQuery query = new TopChildrenQuery(innerQuery, childType, parentType, scoreType, factor, incrementalFactor, parseContext.cacheRecycler());
|
||||||
if (queryName != null) {
|
if (queryName != null) {
|
||||||
parseContext.addNamedQuery(queryName, childQuery);
|
parseContext.addNamedFilter(queryName, new CustomQueryWrappingFilter(query));
|
||||||
}
|
}
|
||||||
return childQuery;
|
return query;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2004,6 +2004,54 @@ public class SimpleChildQuerySearchTests extends ElasticsearchIntegrationTest {
|
||||||
assertThat(searchResponse.getHits().totalHits(), equalTo(2l));
|
assertThat(searchResponse.getHits().totalHits(), equalTo(2l));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNamedFilters() throws Exception {
|
||||||
|
client().admin().indices().prepareCreate("test")
|
||||||
|
.setSettings(ImmutableSettings.settingsBuilder().put("index.number_of_shards", 1).put("index.number_of_replicas", 0))
|
||||||
|
.execute().actionGet();
|
||||||
|
client().admin().cluster().prepareHealth().setWaitForEvents(Priority.LANGUID).setWaitForGreenStatus().execute().actionGet();
|
||||||
|
client().admin()
|
||||||
|
.indices()
|
||||||
|
.preparePutMapping("test")
|
||||||
|
.setType("child")
|
||||||
|
.setSource("_parent", "type=parent").execute().actionGet();
|
||||||
|
|
||||||
|
String parentId = "p1";
|
||||||
|
client().prepareIndex("test", "parent", parentId).setSource("p_field", "1").execute().actionGet();
|
||||||
|
client().prepareIndex("test", "child", "c1").setSource("c_field", "1").setParent(parentId).execute().actionGet();
|
||||||
|
client().admin().indices().prepareRefresh().execute().actionGet();
|
||||||
|
|
||||||
|
SearchResponse searchResponse = client().prepareSearch("test").setQuery(topChildrenQuery("child", termQuery("c_field", "1")).queryName("test"))
|
||||||
|
.execute().actionGet();
|
||||||
|
assertHitCount(searchResponse, 1l);
|
||||||
|
assertThat(searchResponse.getHits().getAt(0).getMatchedQueries().length, equalTo(1));
|
||||||
|
assertThat(searchResponse.getHits().getAt(0).getMatchedQueries()[0], equalTo("test"));
|
||||||
|
|
||||||
|
searchResponse = client().prepareSearch("test").setQuery(hasChildQuery("child", termQuery("c_field", "1")).scoreType("max").queryName("test"))
|
||||||
|
.execute().actionGet();
|
||||||
|
assertHitCount(searchResponse, 1l);
|
||||||
|
assertThat(searchResponse.getHits().getAt(0).getMatchedQueries().length, equalTo(1));
|
||||||
|
assertThat(searchResponse.getHits().getAt(0).getMatchedQueries()[0], equalTo("test"));
|
||||||
|
|
||||||
|
searchResponse = client().prepareSearch("test").setQuery(hasParentQuery("parent", termQuery("p_field", "1")).scoreType("score").queryName("test"))
|
||||||
|
.execute().actionGet();
|
||||||
|
assertHitCount(searchResponse, 1l);
|
||||||
|
assertThat(searchResponse.getHits().getAt(0).getMatchedQueries().length, equalTo(1));
|
||||||
|
assertThat(searchResponse.getHits().getAt(0).getMatchedQueries()[0], equalTo("test"));
|
||||||
|
|
||||||
|
searchResponse = client().prepareSearch("test").setQuery(constantScoreQuery(hasChildFilter("child", termQuery("c_field", "1")).filterName("test")))
|
||||||
|
.execute().actionGet();
|
||||||
|
assertHitCount(searchResponse, 1l);
|
||||||
|
assertThat(searchResponse.getHits().getAt(0).getMatchedQueries().length, equalTo(1));
|
||||||
|
assertThat(searchResponse.getHits().getAt(0).getMatchedQueries()[0], equalTo("test"));
|
||||||
|
|
||||||
|
searchResponse = client().prepareSearch("test").setQuery(constantScoreQuery(hasParentFilter("parent", termQuery("p_field", "1")).filterName("test")))
|
||||||
|
.execute().actionGet();
|
||||||
|
assertHitCount(searchResponse, 1l);
|
||||||
|
assertThat(searchResponse.getHits().getAt(0).getMatchedQueries().length, equalTo(1));
|
||||||
|
assertThat(searchResponse.getHits().getAt(0).getMatchedQueries()[0], equalTo("test"));
|
||||||
|
}
|
||||||
|
|
||||||
private static HasChildFilterBuilder hasChildFilter(String type, QueryBuilder queryBuilder) {
|
private static HasChildFilterBuilder hasChildFilter(String type, QueryBuilder queryBuilder) {
|
||||||
HasChildFilterBuilder hasChildFilterBuilder = FilterBuilders.hasChildFilter(type, queryBuilder);
|
HasChildFilterBuilder hasChildFilterBuilder = FilterBuilders.hasChildFilter(type, queryBuilder);
|
||||||
hasChildFilterBuilder.setShortCircuitCutoff(randomInt(10));
|
hasChildFilterBuilder.setShortCircuitCutoff(randomInt(10));
|
||||||
|
|
Loading…
Reference in New Issue