Added support for the `_cache` and` _cache_key` options to the `has_child` and `has_parent` filters.

Closes #2900
This commit is contained in:
Martijn van Groningen 2013-04-16 14:42:45 +02:00
parent ef5b7412e6
commit 9a1c03408b
6 changed files with 137 additions and 5 deletions

View File

@ -32,6 +32,8 @@ public class HasChildFilterBuilder extends BaseFilterBuilder {
private final QueryBuilder queryBuilder;
private String childType;
private String filterName;
private Boolean cache;
private String cacheKey;
public HasChildFilterBuilder(String type, QueryBuilder queryBuilder) {
this.childType = type;
@ -53,6 +55,23 @@ public class HasChildFilterBuilder extends BaseFilterBuilder {
return this;
}
/**
* Should the filter be cached or not. Defaults to <tt>false</tt>.
*/
public HasChildFilterBuilder cache(boolean cache) {
this.cache = cache;
return this;
}
/**
* Defines what should be used as key to represent this filter in the filter cache.
* By default the filter itself is used as key.
*/
public HasChildFilterBuilder cacheKey(String cacheKey) {
this.cacheKey = cacheKey;
return this;
}
@Override
protected void doXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject(HasChildFilterParser.NAME);
@ -67,6 +86,12 @@ public class HasChildFilterBuilder extends BaseFilterBuilder {
if (filterName != null) {
builder.field("_name", filterName);
}
if (cache != null) {
builder.field("_cache", cache);
}
if (cacheKey != null) {
builder.field("_cache_key", cacheKey);
}
builder.endObject();
}
}

View File

@ -26,6 +26,7 @@ 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.cache.filter.support.CacheKeyFilter;
import org.elasticsearch.index.mapper.DocumentMapper;
import org.elasticsearch.index.search.child.HasChildFilter;
import org.elasticsearch.search.internal.SearchContext;
@ -56,6 +57,8 @@ public class HasChildFilterParser implements FilterParser {
boolean queryFound = false;
String childType = null;
boolean cache = false;
CacheKeyFilter.Key cacheKey = null;
String filterName = null;
String currentFieldName = null;
XContentParser.Token token;
@ -93,6 +96,10 @@ public class HasChildFilterParser implements FilterParser {
throw new QueryParsingException(parseContext.index(), "the [_scope] support in [has_child] filter has been removed, use a filter as a facet_filter in the relevant global facet");
} else if ("_name".equals(currentFieldName)) {
filterName = parser.text();
} else if ("_cache".equals(currentFieldName)) {
cache = parser.booleanValue();
} else if ("_cache_key".equals(currentFieldName) || "_cacheKey".equals(currentFieldName)) {
cacheKey = new CacheKeyFilter.Key(parser.text());
} else {
throw new QueryParsingException(parseContext.index(), "[has_child] filter does not support [" + currentFieldName + "]");
}
@ -124,10 +131,15 @@ public class HasChildFilterParser implements FilterParser {
HasChildFilter childFilter = HasChildFilter.create(query, parentType, childType, searchContext);
searchContext.addRewrite(childFilter);
Filter filter = childFilter;
if (cache) {
filter = parseContext.cacheFilter(filter, cacheKey);
}
if (filterName != null) {
parseContext.addNamedFilter(filterName, childFilter);
parseContext.addNamedFilter(filterName, filter);
}
return childFilter;
return filter;
}
}

View File

@ -32,6 +32,8 @@ public class HasParentFilterBuilder extends BaseFilterBuilder {
private final FilterBuilder filterBuilder;
private final String parentType;
private String filterName;
private Boolean cache;
private String cacheKey;
/**
* @param parentType The parent type
@ -53,11 +55,31 @@ public class HasParentFilterBuilder extends BaseFilterBuilder {
this.filterBuilder = parentFilter;
}
/**
* Sets the filter name for the filter that can be used when searching for matched_filters per hit.
*/
public HasParentFilterBuilder filterName(String filterName) {
this.filterName = filterName;
return this;
}
/**
* Should the filter be cached or not. Defaults to <tt>false</tt>.
*/
public HasParentFilterBuilder cache(boolean cache) {
this.cache = cache;
return this;
}
/**
* Defines what should be used as key to represent this filter in the filter cache.
* By default the filter itself is used as key.
*/
public HasParentFilterBuilder cacheKey(String cacheKey) {
this.cacheKey = cacheKey;
return this;
}
@Override
protected void doXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject(HasParentFilterParser.NAME);
@ -72,6 +94,12 @@ public class HasParentFilterBuilder extends BaseFilterBuilder {
if (filterName != null) {
builder.field("_name", filterName);
}
if (cache != null) {
builder.field("_cache", cache);
}
if (cacheKey != null) {
builder.field("_cache_key", cacheKey);
}
builder.endObject();
}
}

View File

@ -26,6 +26,7 @@ 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.cache.filter.support.CacheKeyFilter;
import org.elasticsearch.index.mapper.DocumentMapper;
import org.elasticsearch.index.search.child.HasParentFilter;
import org.elasticsearch.search.internal.SearchContext;
@ -56,6 +57,8 @@ public class HasParentFilterParser implements FilterParser {
boolean queryFound = false;
String parentType = null;
boolean cache = false;
CacheKeyFilter.Key cacheKey = null;
String filterName = null;
String currentFieldName = null;
XContentParser.Token token;
@ -92,6 +95,10 @@ public class HasParentFilterParser implements FilterParser {
throw new QueryParsingException(parseContext.index(), "the [_scope] support in [has_parent] filter has been removed, use a filter as a facet_filter in the relevant global facet");
} else if ("_name".equals(currentFieldName)) {
filterName = parser.text();
} else if ("_cache".equals(currentFieldName)) {
cache = parser.booleanValue();
} else if ("_cache_key".equals(currentFieldName) || "_cacheKey".equals(currentFieldName)) {
cacheKey = new CacheKeyFilter.Key(parser.text());
} else {
throw new QueryParsingException(parseContext.index(), "[has_parent] filter does not support [" + currentFieldName + "]");
}
@ -120,11 +127,16 @@ public class HasParentFilterParser implements FilterParser {
HasParentFilter parentFilter = HasParentFilter.create(query, parentType, searchContext);
searchContext.addRewrite(parentFilter);
Filter filter = parentFilter;
if (cache) {
filter = parseContext.cacheFilter(filter, cacheKey);
}
if (filterName != null) {
parseContext.addNamedFilter(filterName, parentFilter);
parseContext.addNamedFilter(filterName, filter);
}
return parentFilter;
return filter;
}
}

View File

@ -31,7 +31,6 @@ import org.elasticsearch.common.CacheRecycler;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.bytes.HashedBytesArray;
import org.elasticsearch.common.lucene.docset.MatchDocIdSet;
import org.elasticsearch.common.lucene.search.NoopCollector;
import org.elasticsearch.index.cache.id.IdReaderTypeCache;
import org.elasticsearch.search.internal.SearchContext;
@ -54,6 +53,36 @@ public abstract class HasChildFilter extends Filter implements SearchContext.Rew
this.childQuery = childQuery;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || obj.getClass() != this.getClass()) {
return false;
}
HasChildFilter that = (HasChildFilter) obj;
if (!childQuery.equals(that.childQuery)) {
return false;
}
if (!childType.equals(that.childType)) {
return false;
}
if (!parentType.equals(that.parentType)) {
return false;
}
return true;
}
@Override
public int hashCode() {
int result = childQuery.hashCode();
result = 31 * result + parentType.hashCode();
result = 31 * result + childType.hashCode();
return result;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();

View File

@ -52,6 +52,32 @@ public abstract class HasParentFilter extends Filter implements SearchContext.Re
this.context = context;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || obj.getClass() != this.getClass()) {
return false;
}
HasParentFilter that = (HasParentFilter) obj;
if (!parentQuery.equals(that.parentQuery)) {
return false;
}
if (!parentType.equals(that.parentType)) {
return false;
}
return true;
}
@Override
public int hashCode() {
int result = parentQuery.hashCode();
result = 31 * result + parentType.hashCode();
return result;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();