lucene 4: fix sorting
This commit is contained in:
parent
2b58c2dfff
commit
c2f3eab7d3
|
@ -19,13 +19,12 @@
|
|||
|
||||
package org.apache.lucene.search;
|
||||
|
||||
import org.apache.lucene.util.BytesRef;
|
||||
import org.apache.lucene.util.PriorityQueue;
|
||||
import org.elasticsearch.ElasticSearchIllegalStateException;
|
||||
import org.elasticsearch.search.controller.ShardFieldDoc;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.Collator;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -86,8 +85,8 @@ public class ShardFieldDocSortedHitQueue extends PriorityQueue<ShardFieldDoc> {
|
|||
/**
|
||||
* Returns whether <code>a</code> is less relevant than <code>b</code>.
|
||||
*
|
||||
* @param a ScoreDoc
|
||||
* @param b ScoreDoc
|
||||
* @param docA ScoreDoc
|
||||
* @param docB ScoreDoc
|
||||
* @return <code>true</code> if document <code>a</code> should be sorted after document <code>b</code>.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
|
@ -98,8 +97,8 @@ public class ShardFieldDocSortedHitQueue extends PriorityQueue<ShardFieldDoc> {
|
|||
for (int i = 0; i < n && c == 0; ++i) {
|
||||
final SortField.Type type = fields[i].getType();
|
||||
if (type == SortField.Type.STRING) {
|
||||
final String s1 = (String) docA.fields[i];
|
||||
final String s2 = (String) docB.fields[i];
|
||||
final BytesRef s1 = (BytesRef) docA.fields[i];
|
||||
final BytesRef s2 = (BytesRef) docB.fields[i];
|
||||
// null values need to be sorted first, because of how FieldCache.getStringIndex()
|
||||
// works - in that routine, any documents without a value in the given field are
|
||||
// put first. If both are null, the next SortField is used
|
||||
|
|
|
@ -24,6 +24,7 @@ import org.apache.lucene.analysis.standard.StandardAnalyzer;
|
|||
import org.apache.lucene.index.*;
|
||||
import org.apache.lucene.search.*;
|
||||
import org.apache.lucene.store.Directory;
|
||||
import org.apache.lucene.util.BytesRef;
|
||||
import org.apache.lucene.util.Version;
|
||||
import org.elasticsearch.common.Nullable;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
|
@ -173,6 +174,8 @@ public class Lucene {
|
|||
cFields[j] = in.readShort();
|
||||
} else if (type == 8) {
|
||||
cFields[j] = in.readBoolean();
|
||||
} else if (type == 9) {
|
||||
cFields[j] = in.readBytesRef();
|
||||
} else {
|
||||
throw new IOException("Can't match type [" + type + "]");
|
||||
}
|
||||
|
@ -258,6 +261,9 @@ public class Lucene {
|
|||
} else if (type == Boolean.class) {
|
||||
out.writeByte((byte) 8);
|
||||
out.writeBoolean((Boolean) field);
|
||||
} else if (type == BytesRef.class) {
|
||||
out.writeByte((byte) 9);
|
||||
out.writeBytesRef((BytesRef) field);
|
||||
} else {
|
||||
throw new IOException("Can't handle sort field value of type [" + type + "]");
|
||||
}
|
||||
|
|
|
@ -46,11 +46,15 @@ public abstract class DocFieldData<T extends FieldData> {
|
|||
return !fieldData.hasValue(docId);
|
||||
}
|
||||
|
||||
public BytesRef stringValue() {
|
||||
return fieldData.stringValue(docId);
|
||||
public String stringValue() {
|
||||
BytesRef val = fieldData.stringValue(docId);
|
||||
if (val == null) {
|
||||
return null;
|
||||
}
|
||||
return val.utf8ToString();
|
||||
}
|
||||
|
||||
public BytesRef getStringValue() {
|
||||
public String getStringValue() {
|
||||
return stringValue();
|
||||
}
|
||||
|
||||
|
|
|
@ -31,11 +31,31 @@ public class StringDocFieldData extends DocFieldData<StringFieldData> {
|
|||
super(fieldData);
|
||||
}
|
||||
|
||||
public BytesRef getValue() {
|
||||
public String getValue() {
|
||||
BytesRef value = fieldData.value(docId);
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
return value.utf8ToString();
|
||||
}
|
||||
|
||||
public String[] getValues() {
|
||||
BytesRef[] values = fieldData.values(docId);
|
||||
if (values == null) {
|
||||
return null;
|
||||
}
|
||||
String[] stringValues = new String[values.length];
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
stringValues[i] = values[i].utf8ToString();
|
||||
}
|
||||
return stringValues;
|
||||
}
|
||||
|
||||
public BytesRef getBytesValue() {
|
||||
return fieldData.value(docId);
|
||||
}
|
||||
|
||||
public BytesRef[] getValues() {
|
||||
public BytesRef[] getBytesValues() {
|
||||
return fieldData.values(docId);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ public class FieldDataLoader {
|
|||
|
||||
Terms terms = reader.terms(field);
|
||||
if (terms == null) {
|
||||
return loader.buildSingleValue(field, new int[0]); // Return empty field data if field doesn't exists.
|
||||
return loader.buildSingleValue(field, ordinals.get(0)); // Return empty field data if field doesn't exists.
|
||||
}
|
||||
|
||||
TermsEnum termsEnum = terms.iterator(null);
|
||||
|
|
|
@ -21,6 +21,7 @@ package org.elasticsearch.search.internal;
|
|||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import org.apache.lucene.search.Explanation;
|
||||
import org.apache.lucene.util.BytesRef;
|
||||
import org.elasticsearch.ElasticSearchParseException;
|
||||
import org.elasticsearch.common.Nullable;
|
||||
import org.elasticsearch.common.Strings;
|
||||
|
@ -29,6 +30,7 @@ import org.elasticsearch.common.bytes.BytesReference;
|
|||
import org.elasticsearch.common.compress.CompressorFactory;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
import org.elasticsearch.common.text.StringAndBytesText;
|
||||
import org.elasticsearch.common.text.Text;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilderString;
|
||||
|
@ -295,6 +297,14 @@ public class InternalSearchHit implements SearchHit {
|
|||
}
|
||||
|
||||
public void sortValues(Object[] sortValues) {
|
||||
// LUCENE 4 UPGRADE: There must be a better way
|
||||
if (sortValues != null) {
|
||||
for (int i=0; i<sortValues.length; i++) {
|
||||
if (sortValues[i] instanceof BytesRef) {
|
||||
sortValues[i] = new StringAndBytesText(new BytesArray((BytesRef)sortValues[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
this.sortValues = sortValues;
|
||||
}
|
||||
|
||||
|
@ -571,6 +581,9 @@ public class InternalSearchHit implements SearchHit {
|
|||
sortValues[i] = in.readShort();
|
||||
} else if (type == 8) {
|
||||
sortValues[i] = in.readBoolean();
|
||||
} else if (type == 9) {
|
||||
// LUCENE 4 UPGRADE: There must be a better way
|
||||
sortValues[i] = new StringAndBytesText(new BytesArray(in.readBytesRef()));
|
||||
} else {
|
||||
throw new IOException("Can't match type [" + type + "]");
|
||||
}
|
||||
|
@ -664,6 +677,9 @@ public class InternalSearchHit implements SearchHit {
|
|||
} else if (type == Boolean.class) {
|
||||
out.writeByte((byte) 8);
|
||||
out.writeBoolean((Boolean) sortValue);
|
||||
} else if (type == BytesRef.class) {
|
||||
out.writeByte((byte) 9);
|
||||
out.writeBytesRef((BytesRef) sortValue);
|
||||
} else {
|
||||
throw new IOException("Can't handle sort field value of type [" + type + "]");
|
||||
}
|
||||
|
|
|
@ -82,11 +82,11 @@ public class StringFieldDataTests {
|
|||
// svalue
|
||||
assertThat(sFieldData.hasValue(0), equalTo(true));
|
||||
assertThat(sFieldData.value(0).utf8ToString(), equalTo("zzz"));
|
||||
assertThat(sFieldData.docFieldData(0).getValue().utf8ToString(), equalTo("zzz"));
|
||||
assertThat(sFieldData.docFieldData(0).getValue(), equalTo("zzz"));
|
||||
assertThat(sFieldData.values(0).length, equalTo(1));
|
||||
assertThat(sFieldData.docFieldData(0).getValues().length, equalTo(1));
|
||||
assertThat(sFieldData.values(0)[0].utf8ToString(), equalTo("zzz"));
|
||||
assertThat(sFieldData.docFieldData(0).getValues()[0].utf8ToString(), equalTo("zzz"));
|
||||
assertThat(sFieldData.docFieldData(0).getValues()[0], equalTo("zzz"));
|
||||
|
||||
assertThat(sFieldData.hasValue(1), equalTo(true));
|
||||
assertThat(sFieldData.value(1).utf8ToString(), equalTo("xxx"));
|
||||
|
|
Loading…
Reference in New Issue