Search fails when sorting on a field that has no values in the hits returned, closes #285.

This commit is contained in:
kimchy 2010-07-31 16:41:15 +03:00
parent a26b4f31e1
commit dfb68c6310
3 changed files with 32 additions and 1 deletions

View File

@ -217,6 +217,13 @@ public abstract class TransportSearchTypeAction extends BaseAction<SearchRequest
try {
moveToSecondPhase();
} catch (Exception e) {
if (logger.isDebugEnabled()) {
if (shard != null) {
logger.debug(shard.shortSummary() + ": Failed to execute [" + request + "] while moving to second phase", e);
} else {
logger.debug(shardIt.shardId() + ": Failed to execute [" + request + "] while moving to second phase", e);
}
}
invokeListener(new ReduceSearchPhaseException(firstPhaseName(), "", e, buildShardFailures()));
}
}

View File

@ -80,14 +80,16 @@ public class SearchPhaseController {
}
PriorityQueue queue;
if (queryResultProvider.queryResult().topDocs() instanceof TopFieldDocs) {
// sorting, first if the type is a String, chance CUSTOM to STRING so we handle nulls properly
// sorting, first if the type is a String, chance CUSTOM to STRING so we handle nulls properly (since our CUSTOM String sorting might return null)
TopFieldDocs fieldDocs = (TopFieldDocs) queryResultProvider.queryResult().topDocs();
for (int i = 0; i < fieldDocs.fields.length; i++) {
boolean allValuesAreNull = true;
boolean resolvedField = false;
for (QuerySearchResultProvider resultProvider : results) {
for (ScoreDoc doc : resultProvider.queryResult().topDocs().scoreDocs) {
FieldDoc fDoc = (FieldDoc) doc;
if (fDoc.fields[i] != null) {
allValuesAreNull = false;
if (fDoc.fields[i] instanceof String) {
fieldDocs.fields[i] = new SortField(fieldDocs.fields[i].getField(), SortField.STRING, fieldDocs.fields[i].getReverse());
}
@ -99,6 +101,10 @@ public class SearchPhaseController {
break;
}
}
if (!resolvedField && allValuesAreNull) {
// we did not manage to resolve a field, and all the fields are null (which can only happen for STRING), make it a STRING
fieldDocs.fields[i] = new SortField(fieldDocs.fields[i].getField(), SortField.STRING, fieldDocs.fields[i].getReverse());
}
}
queue = new ShardFieldDocSortedHitQueue(fieldDocs.fields, queueSize);

View File

@ -206,5 +206,23 @@ public class SimpleSortTests extends AbstractNodesTests {
assertThat((String) searchResponse.hits().getAt(0).field("id").value(), equalTo("3"));
assertThat((String) searchResponse.hits().getAt(1).field("id").value(), equalTo("1"));
assertThat((String) searchResponse.hits().getAt(2).field("id").value(), equalTo("2"));
// a query with docs just with null values
searchResponse = client.prepareSearch()
.setQuery(termQuery("id", "2"))
.addScriptField("id", "doc['id'].value")
.addSort("svalue", SearchSourceBuilder.Order.DESC)
.execute().actionGet();
if (searchResponse.failedShards() > 0) {
logger.warn("Failed shards:");
for (ShardSearchFailure shardSearchFailure : searchResponse.shardFailures()) {
logger.warn("-> {}", shardSearchFailure);
}
}
assertThat(searchResponse.failedShards(), equalTo(0));
assertThat(searchResponse.hits().getTotalHits(), equalTo(1l));
assertThat((String) searchResponse.hits().getAt(0).field("id").value(), equalTo("2"));
}
}