Search fails when sorting on a field that has no values in the hits returned, closes #285.
This commit is contained in:
parent
a26b4f31e1
commit
dfb68c6310
|
@ -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()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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"));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue