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 {
|
try {
|
||||||
moveToSecondPhase();
|
moveToSecondPhase();
|
||||||
} catch (Exception e) {
|
} 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()));
|
invokeListener(new ReduceSearchPhaseException(firstPhaseName(), "", e, buildShardFailures()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,14 +80,16 @@ public class SearchPhaseController {
|
||||||
}
|
}
|
||||||
PriorityQueue queue;
|
PriorityQueue queue;
|
||||||
if (queryResultProvider.queryResult().topDocs() instanceof TopFieldDocs) {
|
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();
|
TopFieldDocs fieldDocs = (TopFieldDocs) queryResultProvider.queryResult().topDocs();
|
||||||
for (int i = 0; i < fieldDocs.fields.length; i++) {
|
for (int i = 0; i < fieldDocs.fields.length; i++) {
|
||||||
|
boolean allValuesAreNull = true;
|
||||||
boolean resolvedField = false;
|
boolean resolvedField = false;
|
||||||
for (QuerySearchResultProvider resultProvider : results) {
|
for (QuerySearchResultProvider resultProvider : results) {
|
||||||
for (ScoreDoc doc : resultProvider.queryResult().topDocs().scoreDocs) {
|
for (ScoreDoc doc : resultProvider.queryResult().topDocs().scoreDocs) {
|
||||||
FieldDoc fDoc = (FieldDoc) doc;
|
FieldDoc fDoc = (FieldDoc) doc;
|
||||||
if (fDoc.fields[i] != null) {
|
if (fDoc.fields[i] != null) {
|
||||||
|
allValuesAreNull = false;
|
||||||
if (fDoc.fields[i] instanceof String) {
|
if (fDoc.fields[i] instanceof String) {
|
||||||
fieldDocs.fields[i] = new SortField(fieldDocs.fields[i].getField(), SortField.STRING, fieldDocs.fields[i].getReverse());
|
fieldDocs.fields[i] = new SortField(fieldDocs.fields[i].getField(), SortField.STRING, fieldDocs.fields[i].getReverse());
|
||||||
}
|
}
|
||||||
|
@ -99,6 +101,10 @@ public class SearchPhaseController {
|
||||||
break;
|
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);
|
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(0).field("id").value(), equalTo("3"));
|
||||||
assertThat((String) searchResponse.hits().getAt(1).field("id").value(), equalTo("1"));
|
assertThat((String) searchResponse.hits().getAt(1).field("id").value(), equalTo("1"));
|
||||||
assertThat((String) searchResponse.hits().getAt(2).field("id").value(), equalTo("2"));
|
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