add sort values as part of the response per search hit
This commit is contained in:
parent
7cb2010dda
commit
37af7f5aef
|
@ -134,6 +134,16 @@ public interface SearchHit extends Streamable, ToXContent, Iterable<SearchHitFie
|
|||
*/
|
||||
Map<String, HighlightField> getHighlightFields();
|
||||
|
||||
/**
|
||||
* An array of the sort values used.
|
||||
*/
|
||||
Object[] sortValues();
|
||||
|
||||
/**
|
||||
* An array of the sort values used.
|
||||
*/
|
||||
Object[] getSortValues();
|
||||
|
||||
/**
|
||||
* The shard of the search hit.
|
||||
*/
|
||||
|
|
|
@ -171,6 +171,21 @@ public class SearchPhaseController {
|
|||
}
|
||||
|
||||
public InternalSearchResponse merge(ShardDoc[] sortedDocs, Map<SearchShardTarget, ? extends QuerySearchResultProvider> queryResults, Map<SearchShardTarget, ? extends FetchSearchResultProvider> fetchResults) {
|
||||
|
||||
boolean sorted = false;
|
||||
int sortScoreIndex = -1;
|
||||
QuerySearchResult querySearchResult = Iterables.get(queryResults.values(), 0).queryResult();
|
||||
|
||||
if (querySearchResult.topDocs() instanceof TopFieldDocs) {
|
||||
sorted = true;
|
||||
TopFieldDocs fieldDocs = (TopFieldDocs) querySearchResult.queryResult().topDocs();
|
||||
for (int i = 0; i < fieldDocs.fields.length; i++) {
|
||||
if (fieldDocs.fields[i].getType() == SortField.SCORE) {
|
||||
sortScoreIndex = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// merge facets
|
||||
InternalFacets facets = null;
|
||||
if (!queryResults.isEmpty()) {
|
||||
|
@ -223,6 +238,15 @@ public class SearchPhaseController {
|
|||
InternalSearchHit searchHit = fetchResult.hits().internalHits()[index];
|
||||
searchHit.score(shardDoc.score());
|
||||
searchHit.shard(fetchResult.shardTarget());
|
||||
|
||||
if (sorted) {
|
||||
FieldDoc fieldDoc = (FieldDoc) shardDoc;
|
||||
searchHit.sortValues(fieldDoc.fields);
|
||||
if (sortScoreIndex != -1) {
|
||||
searchHit.score(((Number) fieldDoc.fields[sortScoreIndex]).floatValue());
|
||||
}
|
||||
}
|
||||
|
||||
hits.add(searchHit);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,6 +49,8 @@ import static org.elasticsearch.search.internal.InternalSearchHitField.*;
|
|||
*/
|
||||
public class InternalSearchHit implements SearchHit {
|
||||
|
||||
private static final Object[] EMPTY_SORT_VALUES = new Object[0];
|
||||
|
||||
private transient int docId;
|
||||
|
||||
private float score = Float.NEGATIVE_INFINITY;
|
||||
|
@ -63,6 +65,8 @@ public class InternalSearchHit implements SearchHit {
|
|||
|
||||
private Map<String, HighlightField> highlightFields = ImmutableMap.of();
|
||||
|
||||
private Object[] sortValues = EMPTY_SORT_VALUES;
|
||||
|
||||
private Explanation explanation;
|
||||
|
||||
@Nullable private SearchShardTarget shard;
|
||||
|
@ -195,6 +199,18 @@ public class InternalSearchHit implements SearchHit {
|
|||
this.highlightFields = highlightFields;
|
||||
}
|
||||
|
||||
public void sortValues(Object[] sortValues) {
|
||||
this.sortValues = sortValues;
|
||||
}
|
||||
|
||||
@Override public Object[] sortValues() {
|
||||
return sortValues;
|
||||
}
|
||||
|
||||
@Override public Object[] getSortValues() {
|
||||
return sortValues();
|
||||
}
|
||||
|
||||
@Override public Explanation explanation() {
|
||||
return explanation;
|
||||
}
|
||||
|
@ -274,6 +290,13 @@ public class InternalSearchHit implements SearchHit {
|
|||
}
|
||||
builder.endObject();
|
||||
}
|
||||
if (sortValues != null && sortValues.length > 0) {
|
||||
builder.startArray("sort_values");
|
||||
for (Object sortValue : sortValues) {
|
||||
builder.value(sortValue);
|
||||
}
|
||||
builder.endArray();
|
||||
}
|
||||
if (explanation() != null) {
|
||||
builder.field("_explanation");
|
||||
buildExplanation(builder, explanation());
|
||||
|
@ -391,6 +414,31 @@ public class InternalSearchHit implements SearchHit {
|
|||
highlightFields = builder.build();
|
||||
}
|
||||
|
||||
size = in.readVInt();
|
||||
if (size > 0) {
|
||||
sortValues = new Object[size];
|
||||
for (int i = 0; i < sortValues.length; i++) {
|
||||
byte type = in.readByte();
|
||||
if (type == 0) {
|
||||
sortValues[i] = null;
|
||||
} else if (type == 1) {
|
||||
sortValues[i] = in.readUTF();
|
||||
} else if (type == 2) {
|
||||
sortValues[i] = in.readInt();
|
||||
} else if (type == 3) {
|
||||
sortValues[i] = in.readLong();
|
||||
} else if (type == 4) {
|
||||
sortValues[i] = in.readFloat();
|
||||
} else if (type == 5) {
|
||||
sortValues[i] = in.readDouble();
|
||||
} else if (type == 6) {
|
||||
sortValues[i] = in.readByte();
|
||||
} else {
|
||||
throw new IOException("Can't match type [" + type + "]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (shardLookupMap != null) {
|
||||
int lookupId = in.readVInt();
|
||||
if (lookupId > 0) {
|
||||
|
@ -439,6 +487,41 @@ public class InternalSearchHit implements SearchHit {
|
|||
highlightField.writeTo(out);
|
||||
}
|
||||
}
|
||||
|
||||
if (sortValues.length == 0) {
|
||||
out.writeVInt(0);
|
||||
} else {
|
||||
out.writeVInt(sortValues.length);
|
||||
for (Object sortValue : sortValues) {
|
||||
if (sortValue == null) {
|
||||
out.writeByte((byte) 0);
|
||||
} else {
|
||||
Class type = sortValue.getClass();
|
||||
if (type == String.class) {
|
||||
out.writeByte((byte) 1);
|
||||
out.writeUTF((String) sortValue);
|
||||
} else if (type == Integer.class) {
|
||||
out.writeByte((byte) 2);
|
||||
out.writeInt((Integer) sortValue);
|
||||
} else if (type == Long.class) {
|
||||
out.writeByte((byte) 3);
|
||||
out.writeLong((Long) sortValue);
|
||||
} else if (type == Float.class) {
|
||||
out.writeByte((byte) 4);
|
||||
out.writeFloat((Float) sortValue);
|
||||
} else if (type == Double.class) {
|
||||
out.writeByte((byte) 5);
|
||||
out.writeDouble((Double) sortValue);
|
||||
} else if (type == Byte.class) {
|
||||
out.writeByte((byte) 6);
|
||||
out.writeByte((Byte) sortValue);
|
||||
} else {
|
||||
throw new IOException("Can't handle sort field value of type [" + type + "]");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (shardLookupMap == null) {
|
||||
if (shard == null) {
|
||||
out.writeBoolean(false);
|
||||
|
|
|
@ -88,7 +88,9 @@ public class SimpleSortTests extends AbstractNodesTests {
|
|||
|
||||
assertThat(searchResponse.hits().getTotalHits(), equalTo(2l));
|
||||
assertThat((String) searchResponse.hits().getAt(0).field("id").value(), equalTo("1"));
|
||||
assertThat(searchResponse.hits().getAt(0).sortValues()[0].toString(), equalTo("aaa"));
|
||||
assertThat((String) searchResponse.hits().getAt(1).field("id").value(), equalTo("2"));
|
||||
assertThat(searchResponse.hits().getAt(1).sortValues()[0].toString(), equalTo("bbb"));
|
||||
|
||||
searchResponse = client.prepareSearch()
|
||||
.setQuery(matchAllQuery())
|
||||
|
@ -128,7 +130,9 @@ public class SimpleSortTests extends AbstractNodesTests {
|
|||
|
||||
assertThat(searchResponse.hits().getTotalHits(), equalTo(2l));
|
||||
assertThat((String) searchResponse.hits().getAt(0).field("id").value(), equalTo("1"));
|
||||
assertThat(((Number) searchResponse.hits().getAt(0).sortValues()[0]).longValue(), equalTo(100l));
|
||||
assertThat((String) searchResponse.hits().getAt(1).field("id").value(), equalTo("2"));
|
||||
assertThat(((Number) searchResponse.hits().getAt(1).sortValues()[0]).longValue(), equalTo(200l));
|
||||
|
||||
searchResponse = client.prepareSearch()
|
||||
.setQuery(matchAllQuery())
|
||||
|
@ -148,7 +152,9 @@ public class SimpleSortTests extends AbstractNodesTests {
|
|||
|
||||
assertThat(searchResponse.hits().getTotalHits(), equalTo(2l));
|
||||
assertThat((String) searchResponse.hits().getAt(0).field("id").value(), equalTo("2"));
|
||||
assertThat(((Number) searchResponse.hits().getAt(0).sortValues()[0]).longValue(), equalTo(200l));
|
||||
assertThat((String) searchResponse.hits().getAt(1).field("id").value(), equalTo("1"));
|
||||
assertThat(((Number) searchResponse.hits().getAt(1).sortValues()[0]).longValue(), equalTo(100l));
|
||||
|
||||
searchResponse = client.prepareSearch()
|
||||
.setQuery(matchAllQuery())
|
||||
|
|
Loading…
Reference in New Issue