Returning useful exception when sorting on a completion field

Closes #3747
This commit is contained in:
Alexander Reelsen 2013-09-26 22:49:38 +02:00
parent 4aa315974b
commit a18f47e62e
5 changed files with 38 additions and 0 deletions

View File

@ -202,4 +202,6 @@ public interface FieldMapper<T> {
PostingsFormatProvider postingsFormatProvider(); PostingsFormatProvider postingsFormatProvider();
boolean isNumeric(); boolean isNumeric();
boolean isSortable();
} }

View File

@ -711,4 +711,8 @@ public abstract class AbstractFieldMapper<T> implements FieldMapper<T>, Mapper {
return false; return false;
} }
@Override
public boolean isSortable() {
return true;
}
} }

View File

@ -357,6 +357,10 @@ public class CompletionFieldMapper extends AbstractFieldMapper<String> {
return CONTENT_TYPE; return CONTENT_TYPE;
} }
@Override
public boolean isSortable() {
return false;
}
@Override @Override
public FieldType defaultFieldType() { public FieldType defaultFieldType() {

View File

@ -31,6 +31,7 @@ import org.elasticsearch.index.fielddata.IndexFieldData;
import org.elasticsearch.index.fielddata.fieldcomparator.SortMode; import org.elasticsearch.index.fielddata.fieldcomparator.SortMode;
import org.elasticsearch.index.mapper.FieldMapper; import org.elasticsearch.index.mapper.FieldMapper;
import org.elasticsearch.index.mapper.ObjectMappers; import org.elasticsearch.index.mapper.ObjectMappers;
import org.elasticsearch.index.mapper.core.CompletionFieldMapper;
import org.elasticsearch.index.mapper.core.NumberFieldMapper; import org.elasticsearch.index.mapper.core.NumberFieldMapper;
import org.elasticsearch.index.mapper.object.ObjectMapper; import org.elasticsearch.index.mapper.object.ObjectMapper;
import org.elasticsearch.index.query.ParsedFilter; import org.elasticsearch.index.query.ParsedFilter;
@ -198,6 +199,10 @@ public class SortParseElement implements SearchParseElement {
throw new SearchParseException(context, "No mapping found for [" + fieldName + "] in order to sort on"); throw new SearchParseException(context, "No mapping found for [" + fieldName + "] in order to sort on");
} }
if (!fieldMapper.isSortable()) {
throw new SearchParseException(context, "Sorting not supported for field[" + fieldName + "]");
}
// Enable when we also know how to detect fields that do tokenize, but only emit one token // Enable when we also know how to detect fields that do tokenize, but only emit one token
/*if (fieldMapper instanceof StringFieldMapper) { /*if (fieldMapper instanceof StringFieldMapper) {
StringFieldMapper stringFieldMapper = (StringFieldMapper) fieldMapper; StringFieldMapper stringFieldMapper = (StringFieldMapper) fieldMapper;

View File

@ -27,6 +27,7 @@ import org.elasticsearch.action.admin.indices.segments.IndexShardSegments;
import org.elasticsearch.action.admin.indices.segments.ShardSegments; import org.elasticsearch.action.admin.indices.segments.ShardSegments;
import org.elasticsearch.action.admin.indices.stats.IndicesStatsResponse; import org.elasticsearch.action.admin.indices.stats.IndicesStatsResponse;
import org.elasticsearch.action.index.IndexRequestBuilder; import org.elasticsearch.action.index.IndexRequestBuilder;
import org.elasticsearch.action.search.SearchPhaseExecutionException;
import org.elasticsearch.action.suggest.SuggestResponse; import org.elasticsearch.action.suggest.SuggestResponse;
import org.elasticsearch.common.settings.ImmutableSettings; import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
@ -34,6 +35,7 @@ import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.index.mapper.MapperException; import org.elasticsearch.index.mapper.MapperException;
import org.elasticsearch.index.mapper.MapperParsingException; import org.elasticsearch.index.mapper.MapperParsingException;
import org.elasticsearch.index.mapper.core.CompletionFieldMapper; import org.elasticsearch.index.mapper.core.CompletionFieldMapper;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.suggest.completion.CompletionStats; import org.elasticsearch.search.suggest.completion.CompletionStats;
import org.elasticsearch.search.suggest.completion.CompletionSuggestion; import org.elasticsearch.search.suggest.completion.CompletionSuggestion;
import org.elasticsearch.search.suggest.completion.CompletionSuggestionBuilder; import org.elasticsearch.search.suggest.completion.CompletionSuggestionBuilder;
@ -556,6 +558,27 @@ public class CompletionSuggestSearchTests extends AbstractIntegrationTest {
assertThat(regexSizeInBytes, is(totalSizeInBytes)); assertThat(regexSizeInBytes, is(totalSizeInBytes));
} }
@Test
public void testThatSortingOnCompletionFieldReturnsUsefulException() throws Exception {
createIndexAndMapping();
client().prepareIndex(INDEX, TYPE, "1").setSource(jsonBuilder()
.startObject().startObject(FIELD)
.startArray("input").value("Nirvana").endArray()
.endObject().endObject()
).get();
refresh();
try {
client().prepareSearch(INDEX).setTypes(TYPE).addSort(new FieldSortBuilder(FIELD)).execute().actionGet();
fail("Expected an exception due to trying to sort on completion field, but did not happen");
} catch (SearchPhaseExecutionException e) {
assertThat(e.status().getStatus(), is(400));
assertThat(e.getMessage(), containsString("Sorting not supported for field[" + FIELD + "]"));
}
}
public void assertSuggestions(String suggestion, String... suggestions) { public void assertSuggestions(String suggestion, String... suggestions) {
String suggestionName = RandomStrings.randomAsciiOfLength(new Random(), 10); String suggestionName = RandomStrings.randomAsciiOfLength(new Random(), 10);
SuggestResponse suggestResponse = client().prepareSuggest(INDEX).addSuggestion( SuggestResponse suggestResponse = client().prepareSuggest(INDEX).addSuggestion(