explain score: fix explanation streaming

Complex explanations were always read as Explanations. Depending
on if the response was streamed or not the explanation was
therefore generated by a ComplexExplanation or by a regular
Explanation.

closes #7257
This commit is contained in:
Britta Weber 2014-08-13 14:47:40 +02:00
parent 92ae3c84fe
commit a92300c5b5
2 changed files with 63 additions and 4 deletions

View File

@ -440,9 +440,17 @@ public class Lucene {
} }
public static Explanation readExplanation(StreamInput in) throws IOException { public static Explanation readExplanation(StreamInput in) throws IOException {
float value = in.readFloat(); Explanation explanation;
String description = in.readString(); if (in.getVersion().onOrAfter(org.elasticsearch.Version.V_1_4_0) && in.readBoolean()) {
Explanation explanation = new Explanation(value, description); Boolean match = in.readOptionalBoolean();
explanation = new ComplexExplanation();
((ComplexExplanation) explanation).setMatch(match);
} else {
explanation = new Explanation();
}
explanation.setValue(in.readFloat());
explanation.setDescription(in.readString());
if (in.readBoolean()) { if (in.readBoolean()) {
int size = in.readVInt(); int size = in.readVInt();
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
@ -453,6 +461,15 @@ public class Lucene {
} }
public static void writeExplanation(StreamOutput out, Explanation explanation) throws IOException { public static void writeExplanation(StreamOutput out, Explanation explanation) throws IOException {
if (out.getVersion().onOrAfter(org.elasticsearch.Version.V_1_4_0)) {
if (explanation instanceof ComplexExplanation) {
out.writeBoolean(true);
out.writeOptionalBoolean(((ComplexExplanation) explanation).getMatch());
} else {
out.writeBoolean(false);
}
}
out.writeFloat(explanation.getValue()); out.writeFloat(explanation.getValue());
out.writeString(explanation.getDescription()); out.writeString(explanation.getDescription());
Explanation[] subExplanations = explanation.getDetails(); Explanation[] subExplanations = explanation.getDetails();

View File

@ -19,8 +19,13 @@
package org.elasticsearch.explain; package org.elasticsearch.explain;
import org.apache.lucene.search.ComplexExplanation;
import org.apache.lucene.search.Explanation;
import org.elasticsearch.action.admin.indices.alias.Alias; import org.elasticsearch.action.admin.indices.alias.Alias;
import org.elasticsearch.action.explain.ExplainResponse; import org.elasticsearch.action.explain.ExplainResponse;
import org.elasticsearch.common.io.stream.InputStreamStreamInput;
import org.elasticsearch.common.io.stream.OutputStreamStreamOutput;
import org.elasticsearch.common.lucene.Lucene;
import org.elasticsearch.common.settings.ImmutableSettings; import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.index.query.FilterBuilders; import org.elasticsearch.index.query.FilterBuilders;
import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.index.query.QueryBuilders;
@ -30,6 +35,8 @@ import org.joda.time.DateTimeZone;
import org.joda.time.format.ISODateTimeFormat; import org.joda.time.format.ISODateTimeFormat;
import org.junit.Test; import org.junit.Test;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.Map; import java.util.Map;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
@ -256,8 +263,43 @@ public class ExplainActionTests extends ElasticsearchIntegrationTest {
assertThat(explainResponse.isExists(), equalTo(true)); assertThat(explainResponse.isExists(), equalTo(true));
assertThat(explainResponse.isMatch(), equalTo(true)); assertThat(explainResponse.isMatch(), equalTo(true));
} }
private static String indexOrAlias() { private static String indexOrAlias() {
return randomBoolean() ? "test" : "alias"; return randomBoolean() ? "test" : "alias";
} }
@Test
public void streamExplainTest() throws Exception {
Explanation exp = new Explanation((float) 2.0, "some explanation");
// write
ByteArrayOutputStream outBuffer = new ByteArrayOutputStream();
OutputStreamStreamOutput out = new OutputStreamStreamOutput(outBuffer);
Lucene.writeExplanation(out, exp);
// read
ByteArrayInputStream esInBuffer = new ByteArrayInputStream(outBuffer.toByteArray());
InputStreamStreamInput esBuffer = new InputStreamStreamInput(esInBuffer);
Explanation result = Lucene.readExplanation(esBuffer);
assertThat(exp.toString(),equalTo(result.toString()));
exp = new ComplexExplanation(true, 2.0f, "some explanation");
exp.addDetail(new Explanation(2.0f,"another explanation"));
// write complex
outBuffer = new ByteArrayOutputStream();
out = new OutputStreamStreamOutput(outBuffer);
Lucene.writeExplanation(out, exp);
// read complex
esInBuffer = new ByteArrayInputStream(outBuffer.toByteArray());
esBuffer = new InputStreamStreamInput(esInBuffer);
result = Lucene.readExplanation(esBuffer);
assertThat(exp.toString(),equalTo(result.toString()));
}
} }