lucene 4: fix sorting

This commit is contained in:
Igor Motov 2012-11-06 11:52:14 -05:00 committed by Shay Banon
parent 2b58c2dfff
commit c2f3eab7d3
7 changed files with 59 additions and 14 deletions

View File

@ -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

View File

@ -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 + "]");
}

View File

@ -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();
}

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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 + "]");
}

View File

@ -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"));