mirror of
https://github.com/honeymoose/OpenSearch.git
synced 2025-02-17 18:35:25 +00:00
Added sort_mode
option that defines what value to pick in the case the sort field is multi-valued.
The `min` and `max` sort modes are supported for all field types. Either the lowest value or the highest value is picked. In addition to that number based fields also support `sum` and `avg` as sort mode. If `sum` sort mode is used then all the values for a field and belonging to a document are added together and the result of that is used as sort value. If the `avg` sort mode is used then the average of all values for the sort field belonging to that document is used as sort value. Relates to #2634
This commit is contained in:
parent
7d13545e33
commit
fc13499ff5
@ -27,6 +27,7 @@ import org.elasticsearch.common.Nullable;
|
|||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.index.Index;
|
import org.elasticsearch.index.Index;
|
||||||
import org.elasticsearch.index.IndexComponent;
|
import org.elasticsearch.index.IndexComponent;
|
||||||
|
import org.elasticsearch.index.fielddata.fieldcomparator.SortMode;
|
||||||
import org.elasticsearch.index.mapper.FieldMapper;
|
import org.elasticsearch.index.mapper.FieldMapper;
|
||||||
import org.elasticsearch.index.settings.IndexSettings;
|
import org.elasticsearch.index.settings.IndexSettings;
|
||||||
|
|
||||||
@ -57,7 +58,7 @@ public interface IndexFieldData<FD extends AtomicFieldData> extends IndexCompone
|
|||||||
/**
|
/**
|
||||||
* Comparator used for sorting.
|
* Comparator used for sorting.
|
||||||
*/
|
*/
|
||||||
XFieldComparatorSource comparatorSource(@Nullable Object missingValue);
|
XFieldComparatorSource comparatorSource(@Nullable Object missingValue, SortMode sortMode);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears any resources associated with this field data.
|
* Clears any resources associated with this field data.
|
||||||
|
@ -19,18 +19,18 @@
|
|||||||
|
|
||||||
package org.elasticsearch.index.fielddata.fieldcomparator;
|
package org.elasticsearch.index.fielddata.fieldcomparator;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import org.elasticsearch.index.fielddata.IndexNumericFieldData;
|
import org.elasticsearch.index.fielddata.IndexNumericFieldData;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
public final class ByteValuesComparator extends LongValuesComparatorBase<Byte> {
|
public final class ByteValuesComparator extends LongValuesComparatorBase<Byte> {
|
||||||
|
|
||||||
private final byte[] values;
|
private final byte[] values;
|
||||||
|
|
||||||
public ByteValuesComparator(IndexNumericFieldData<?> indexFieldData, byte missingValue, int numHits, boolean reversed) {
|
public ByteValuesComparator(IndexNumericFieldData<?> indexFieldData, byte missingValue, int numHits, SortMode sortMode) {
|
||||||
super(indexFieldData, missingValue, reversed);
|
super(indexFieldData, missingValue, sortMode);
|
||||||
this.values = new byte[numHits];
|
this.values = new byte[numHits];
|
||||||
assert indexFieldData.getNumericType().requiredBits() <= 8;
|
assert indexFieldData.getNumericType().requiredBits() <= 8;
|
||||||
}
|
}
|
||||||
|
@ -33,10 +33,12 @@ public class ByteValuesComparatorSource extends IndexFieldData.XFieldComparatorS
|
|||||||
|
|
||||||
private final IndexNumericFieldData<?> indexFieldData;
|
private final IndexNumericFieldData<?> indexFieldData;
|
||||||
private final Object missingValue;
|
private final Object missingValue;
|
||||||
|
private final SortMode sortMode;
|
||||||
|
|
||||||
public ByteValuesComparatorSource(IndexNumericFieldData<?> indexFieldData, @Nullable Object missingValue) {
|
public ByteValuesComparatorSource(IndexNumericFieldData<?> indexFieldData, @Nullable Object missingValue, SortMode sortMode) {
|
||||||
this.indexFieldData = indexFieldData;
|
this.indexFieldData = indexFieldData;
|
||||||
this.missingValue = missingValue;
|
this.missingValue = missingValue;
|
||||||
|
this.sortMode = sortMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -57,6 +59,6 @@ public class ByteValuesComparatorSource extends IndexFieldData.XFieldComparatorS
|
|||||||
dMissingValue = missingValue instanceof Number ? ((Number) missingValue).byteValue() : Byte.parseByte(missingValue.toString());
|
dMissingValue = missingValue instanceof Number ? ((Number) missingValue).byteValue() : Byte.parseByte(missingValue.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ByteValuesComparator(indexFieldData, dMissingValue, numHits, reversed);
|
return new ByteValuesComparator(indexFieldData, dMissingValue, numHits, sortMode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,9 +30,11 @@ import java.io.IOException;
|
|||||||
public class BytesRefFieldComparatorSource extends IndexFieldData.XFieldComparatorSource {
|
public class BytesRefFieldComparatorSource extends IndexFieldData.XFieldComparatorSource {
|
||||||
|
|
||||||
private final IndexFieldData<?> indexFieldData;
|
private final IndexFieldData<?> indexFieldData;
|
||||||
|
private final SortMode sortMode;
|
||||||
|
|
||||||
public BytesRefFieldComparatorSource(IndexFieldData<?> indexFieldData) {
|
public BytesRefFieldComparatorSource(IndexFieldData<?> indexFieldData, SortMode sortMode) {
|
||||||
this.indexFieldData = indexFieldData;
|
this.indexFieldData = indexFieldData;
|
||||||
|
this.sortMode = sortMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -44,8 +46,8 @@ public class BytesRefFieldComparatorSource extends IndexFieldData.XFieldComparat
|
|||||||
public FieldComparator<?> newComparator(String fieldname, int numHits, int sortPos, boolean reversed) throws IOException {
|
public FieldComparator<?> newComparator(String fieldname, int numHits, int sortPos, boolean reversed) throws IOException {
|
||||||
assert fieldname.equals(indexFieldData.getFieldNames().indexName());
|
assert fieldname.equals(indexFieldData.getFieldNames().indexName());
|
||||||
if (indexFieldData.valuesOrdered() && indexFieldData instanceof IndexFieldData.WithOrdinals) {
|
if (indexFieldData.valuesOrdered() && indexFieldData instanceof IndexFieldData.WithOrdinals) {
|
||||||
return new BytesRefOrdValComparator((IndexFieldData.WithOrdinals<?>) indexFieldData, numHits, reversed);
|
return new BytesRefOrdValComparator((IndexFieldData.WithOrdinals<?>) indexFieldData, numHits, sortMode);
|
||||||
}
|
}
|
||||||
return new BytesRefValComparator(indexFieldData, numHits, reversed);
|
return new BytesRefValComparator(indexFieldData, numHits, sortMode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ public final class BytesRefOrdValComparator extends FieldComparator<BytesRef> {
|
|||||||
@lucene.internal */
|
@lucene.internal */
|
||||||
final int[] ords;
|
final int[] ords;
|
||||||
|
|
||||||
final boolean reversed;
|
final SortMode sortMode;
|
||||||
|
|
||||||
/* Values for each slot.
|
/* Values for each slot.
|
||||||
@lucene.internal */
|
@lucene.internal */
|
||||||
@ -89,9 +89,9 @@ public final class BytesRefOrdValComparator extends FieldComparator<BytesRef> {
|
|||||||
|
|
||||||
final BytesRef tempBR = new BytesRef();
|
final BytesRef tempBR = new BytesRef();
|
||||||
|
|
||||||
public BytesRefOrdValComparator(IndexFieldData.WithOrdinals<?> indexFieldData, int numHits, boolean reversed) {
|
public BytesRefOrdValComparator(IndexFieldData.WithOrdinals<?> indexFieldData, int numHits, SortMode sortMode) {
|
||||||
this.indexFieldData = indexFieldData;
|
this.indexFieldData = indexFieldData;
|
||||||
this.reversed = reversed;
|
this.sortMode = sortMode;
|
||||||
ords = new int[numHits];
|
ords = new int[numHits];
|
||||||
values = new BytesRef[numHits];
|
values = new BytesRef[numHits];
|
||||||
readerGen = new int[numHits];
|
readerGen = new int[numHits];
|
||||||
@ -487,7 +487,7 @@ public final class BytesRefOrdValComparator extends FieldComparator<BytesRef> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compareBottom(int doc) throws IOException {
|
public int compareBottom(int doc) throws IOException {
|
||||||
final int docOrd = getRelevantOrd(readerOrds, doc, reversed);
|
final int docOrd = getRelevantOrd(readerOrds, doc, sortMode);
|
||||||
if (bottomSameReader) {
|
if (bottomSameReader) {
|
||||||
// ord is precisely comparable, even in the equal case
|
// ord is precisely comparable, even in the equal case
|
||||||
return bottomOrd - docOrd;
|
return bottomOrd - docOrd;
|
||||||
@ -503,7 +503,7 @@ public final class BytesRefOrdValComparator extends FieldComparator<BytesRef> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void copy(int slot, int doc) throws IOException {
|
public void copy(int slot, int doc) throws IOException {
|
||||||
final int ord = getRelevantOrd(readerOrds, doc, reversed);
|
final int ord = getRelevantOrd(readerOrds, doc, sortMode);
|
||||||
ords[slot] = ord;
|
ords[slot] = ord;
|
||||||
if (ord == 0) {
|
if (ord == 0) {
|
||||||
values[slot] = null;
|
values[slot] = null;
|
||||||
@ -519,7 +519,7 @@ public final class BytesRefOrdValComparator extends FieldComparator<BytesRef> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compareDocToValue(int doc, BytesRef value) {
|
public int compareDocToValue(int doc, BytesRef value) {
|
||||||
BytesRef docValue = getRelevantValue(termsIndex, doc, reversed);
|
BytesRef docValue = getRelevantValue(termsIndex, doc, sortMode);
|
||||||
if (docValue == null) {
|
if (docValue == null) {
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
return 0;
|
return 0;
|
||||||
@ -533,7 +533,7 @@ public final class BytesRefOrdValComparator extends FieldComparator<BytesRef> {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static BytesRef getRelevantValue(BytesValues.WithOrdinals readerValues, int docId, boolean reversed) {
|
static BytesRef getRelevantValue(BytesValues.WithOrdinals readerValues, int docId, SortMode sortMode) {
|
||||||
BytesValues.Iter iter = readerValues.getIter(docId);
|
BytesValues.Iter iter = readerValues.getIter(docId);
|
||||||
if (!iter.hasNext()) {
|
if (!iter.hasNext()) {
|
||||||
return null;
|
return null;
|
||||||
@ -543,7 +543,7 @@ public final class BytesRefOrdValComparator extends FieldComparator<BytesRef> {
|
|||||||
BytesRef relevantVal = currentVal;
|
BytesRef relevantVal = currentVal;
|
||||||
while (true) {
|
while (true) {
|
||||||
int cmp = currentVal.compareTo(relevantVal);
|
int cmp = currentVal.compareTo(relevantVal);
|
||||||
if (reversed) {
|
if (sortMode == SortMode.MAX) {
|
||||||
if (cmp > 0) {
|
if (cmp > 0) {
|
||||||
relevantVal = currentVal;
|
relevantVal = currentVal;
|
||||||
}
|
}
|
||||||
@ -560,7 +560,7 @@ public final class BytesRefOrdValComparator extends FieldComparator<BytesRef> {
|
|||||||
return relevantVal;
|
return relevantVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int getRelevantOrd(Ordinals.Docs readerOrds, int docId, boolean reversed) {
|
static int getRelevantOrd(Ordinals.Docs readerOrds, int docId, SortMode sortMode) {
|
||||||
Ordinals.Docs.Iter iter = readerOrds.getIter(docId);
|
Ordinals.Docs.Iter iter = readerOrds.getIter(docId);
|
||||||
int currentVal = iter.next();
|
int currentVal = iter.next();
|
||||||
if (currentVal == 0) {
|
if (currentVal == 0) {
|
||||||
@ -569,7 +569,7 @@ public final class BytesRefOrdValComparator extends FieldComparator<BytesRef> {
|
|||||||
|
|
||||||
int relevantVal = currentVal;
|
int relevantVal = currentVal;
|
||||||
while (true) {
|
while (true) {
|
||||||
if (reversed) {
|
if (sortMode == SortMode.MAX) {
|
||||||
if (currentVal > relevantVal) {
|
if (currentVal > relevantVal) {
|
||||||
relevantVal = currentVal;
|
relevantVal = currentVal;
|
||||||
}
|
}
|
||||||
|
@ -37,14 +37,14 @@ import java.io.IOException;
|
|||||||
public final class BytesRefValComparator extends FieldComparator<BytesRef> {
|
public final class BytesRefValComparator extends FieldComparator<BytesRef> {
|
||||||
|
|
||||||
private final IndexFieldData<?> indexFieldData;
|
private final IndexFieldData<?> indexFieldData;
|
||||||
private final boolean reversed;
|
private final SortMode sortMode;
|
||||||
|
|
||||||
private final BytesRef[] values;
|
private final BytesRef[] values;
|
||||||
private BytesRef bottom;
|
private BytesRef bottom;
|
||||||
private BytesValues docTerms;
|
private BytesValues docTerms;
|
||||||
|
|
||||||
BytesRefValComparator(IndexFieldData<?> indexFieldData, int numHits, boolean reversed) {
|
BytesRefValComparator(IndexFieldData<?> indexFieldData, int numHits, SortMode sortMode) {
|
||||||
this.reversed = reversed;
|
this.sortMode = sortMode;
|
||||||
values = new BytesRef[numHits];
|
values = new BytesRef[numHits];
|
||||||
this.indexFieldData = indexFieldData;
|
this.indexFieldData = indexFieldData;
|
||||||
}
|
}
|
||||||
@ -74,7 +74,7 @@ public final class BytesRefValComparator extends FieldComparator<BytesRef> {
|
|||||||
public FieldComparator<BytesRef> setNextReader(AtomicReaderContext context) throws IOException {
|
public FieldComparator<BytesRef> setNextReader(AtomicReaderContext context) throws IOException {
|
||||||
docTerms = indexFieldData.load(context).getBytesValues();
|
docTerms = indexFieldData.load(context).getBytesValues();
|
||||||
if (docTerms.isMultiValued()) {
|
if (docTerms.isMultiValued()) {
|
||||||
docTerms = new MultiValuedBytesWrapper(docTerms, reversed);
|
docTerms = new MultiValuedBytesWrapper(docTerms, sortMode);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -150,11 +150,11 @@ public final class BytesRefValComparator extends FieldComparator<BytesRef> {
|
|||||||
|
|
||||||
private static final class MultiValuedBytesWrapper extends FilteredByteValues {
|
private static final class MultiValuedBytesWrapper extends FilteredByteValues {
|
||||||
|
|
||||||
private final boolean reversed;
|
private final SortMode sortMode;
|
||||||
|
|
||||||
public MultiValuedBytesWrapper(BytesValues delegate, boolean reversed) {
|
public MultiValuedBytesWrapper(BytesValues delegate, SortMode sortMode) {
|
||||||
super(delegate);
|
super(delegate);
|
||||||
this.reversed = reversed;
|
this.sortMode = sortMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -168,7 +168,7 @@ public final class BytesRefValComparator extends FieldComparator<BytesRef> {
|
|||||||
BytesRef relevantVal = currentVal;
|
BytesRef relevantVal = currentVal;
|
||||||
while (true) {
|
while (true) {
|
||||||
int cmp = currentVal.compareTo(relevantVal);
|
int cmp = currentVal.compareTo(relevantVal);
|
||||||
if (reversed) {
|
if (sortMode == SortMode.MAX) {
|
||||||
if (cmp > 0) {
|
if (cmp > 0) {
|
||||||
relevantVal = currentVal;
|
relevantVal = currentVal;
|
||||||
}
|
}
|
||||||
|
@ -19,18 +19,18 @@
|
|||||||
|
|
||||||
package org.elasticsearch.index.fielddata.fieldcomparator;
|
package org.elasticsearch.index.fielddata.fieldcomparator;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import org.elasticsearch.index.fielddata.IndexNumericFieldData;
|
import org.elasticsearch.index.fielddata.IndexNumericFieldData;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
public final class DoubleValuesComparator extends DoubleValuesComparatorBase<Double> {
|
public final class DoubleValuesComparator extends DoubleValuesComparatorBase<Double> {
|
||||||
|
|
||||||
private final double[] values;
|
private final double[] values;
|
||||||
|
|
||||||
public DoubleValuesComparator(IndexNumericFieldData<?> indexFieldData, double missingValue, int numHits, boolean reversed) {
|
public DoubleValuesComparator(IndexNumericFieldData<?> indexFieldData, double missingValue, int numHits, SortMode sortMode) {
|
||||||
super(indexFieldData, missingValue, reversed);
|
super(indexFieldData, missingValue, sortMode);
|
||||||
assert indexFieldData.getNumericType().requiredBits() <= 64;
|
assert indexFieldData.getNumericType().requiredBits() <= 64;
|
||||||
this.values = new double[numHits];
|
this.values = new double[numHits];
|
||||||
}
|
}
|
||||||
|
@ -17,25 +17,26 @@ package org.elasticsearch.index.fielddata.fieldcomparator;
|
|||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import org.apache.lucene.index.AtomicReaderContext;
|
import org.apache.lucene.index.AtomicReaderContext;
|
||||||
import org.apache.lucene.search.FieldComparator;
|
import org.apache.lucene.search.FieldComparator;
|
||||||
import org.elasticsearch.index.fielddata.DoubleValues;
|
import org.elasticsearch.index.fielddata.DoubleValues;
|
||||||
import org.elasticsearch.index.fielddata.IndexNumericFieldData;
|
import org.elasticsearch.index.fielddata.IndexNumericFieldData;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
abstract class DoubleValuesComparatorBase<T extends Number> extends FieldComparator<T> {
|
abstract class DoubleValuesComparatorBase<T extends Number> extends FieldComparator<T> {
|
||||||
|
|
||||||
protected final IndexNumericFieldData<?>indexFieldData;
|
protected final IndexNumericFieldData<?> indexFieldData;
|
||||||
protected final double missingValue;
|
protected final double missingValue;
|
||||||
protected double bottom;
|
protected double bottom;
|
||||||
protected DoubleValues readerValues;
|
protected DoubleValues readerValues;
|
||||||
private final boolean reversed;
|
private final SortMode sortMode;
|
||||||
|
|
||||||
public DoubleValuesComparatorBase(IndexNumericFieldData<?> indexFieldData, double missingValue, boolean reversed) {
|
public DoubleValuesComparatorBase(IndexNumericFieldData<?> indexFieldData, double missingValue, SortMode sortMode) {
|
||||||
this.indexFieldData = indexFieldData;
|
this.indexFieldData = indexFieldData;
|
||||||
this.missingValue = missingValue;
|
this.missingValue = missingValue;
|
||||||
this.reversed = reversed;
|
this.sortMode = sortMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -43,23 +44,23 @@ abstract class DoubleValuesComparatorBase<T extends Number> extends FieldCompara
|
|||||||
final double v2 = readerValues.getValueMissing(doc, missingValue);
|
final double v2 = readerValues.getValueMissing(doc, missingValue);
|
||||||
return compare(bottom, v2);
|
return compare(bottom, v2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final int compareDocToValue(int doc, T valueObj) throws IOException {
|
public final int compareDocToValue(int doc, T valueObj) throws IOException {
|
||||||
final double value = valueObj.doubleValue();
|
final double value = valueObj.doubleValue();
|
||||||
final double docValue = readerValues.getValueMissing(doc, missingValue);
|
final double docValue = readerValues.getValueMissing(doc, missingValue);
|
||||||
return compare(docValue, value);
|
return compare(docValue, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final FieldComparator<T> setNextReader(AtomicReaderContext context) throws IOException {
|
public final FieldComparator<T> setNextReader(AtomicReaderContext context) throws IOException {
|
||||||
readerValues = indexFieldData.load(context).getDoubleValues();
|
readerValues = indexFieldData.load(context).getDoubleValues();
|
||||||
if (readerValues.isMultiValued()) {
|
if (readerValues.isMultiValued()) {
|
||||||
readerValues = new MultiValuedBytesWrapper(readerValues, reversed);
|
readerValues = new MultiValuedBytesWrapper(readerValues, sortMode);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
static final int compare(double left, double right) {
|
static final int compare(double left, double right) {
|
||||||
if (left > right) {
|
if (left > right) {
|
||||||
return 1;
|
return 1;
|
||||||
@ -69,14 +70,14 @@ abstract class DoubleValuesComparatorBase<T extends Number> extends FieldCompara
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static final class MultiValuedBytesWrapper extends DoubleValues.FilteredDoubleValues {
|
static final class MultiValuedBytesWrapper extends DoubleValues.FilteredDoubleValues {
|
||||||
|
|
||||||
private final boolean reversed;
|
private final SortMode sortMode;
|
||||||
|
|
||||||
public MultiValuedBytesWrapper(DoubleValues delegate, boolean reversed) {
|
public MultiValuedBytesWrapper(DoubleValues delegate, SortMode sortMode) {
|
||||||
super(delegate);
|
super(delegate);
|
||||||
this.reversed = reversed;
|
this.sortMode = sortMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -88,23 +89,35 @@ abstract class DoubleValuesComparatorBase<T extends Number> extends FieldCompara
|
|||||||
|
|
||||||
double currentVal = iter.next();
|
double currentVal = iter.next();
|
||||||
double relevantVal = currentVal;
|
double relevantVal = currentVal;
|
||||||
while (true) {
|
int counter = 1;
|
||||||
int cmp = Double.compare(currentVal, relevantVal);
|
while (iter.hasNext()) {
|
||||||
if (reversed) {
|
|
||||||
if (cmp > 0) {
|
|
||||||
relevantVal = currentVal;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (cmp < 0) {
|
|
||||||
relevantVal = currentVal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!iter.hasNext()) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
currentVal = iter.next();
|
currentVal = iter.next();
|
||||||
|
int cmp = Double.compare(currentVal, relevantVal);
|
||||||
|
switch (sortMode) {
|
||||||
|
case SUM:
|
||||||
|
relevantVal += currentVal;
|
||||||
|
break;
|
||||||
|
case AVG:
|
||||||
|
relevantVal += currentVal;
|
||||||
|
counter++;
|
||||||
|
break;
|
||||||
|
case MIN:
|
||||||
|
if (cmp < 0) {
|
||||||
|
relevantVal = currentVal;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MAX:
|
||||||
|
if (cmp > 0) {
|
||||||
|
relevantVal = currentVal;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sortMode == SortMode.AVG) {
|
||||||
|
return relevantVal / counter;
|
||||||
|
} else {
|
||||||
|
return relevantVal;
|
||||||
}
|
}
|
||||||
return relevantVal;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -33,10 +33,12 @@ public class DoubleValuesComparatorSource extends IndexFieldData.XFieldComparato
|
|||||||
|
|
||||||
private final IndexNumericFieldData<?> indexFieldData;
|
private final IndexNumericFieldData<?> indexFieldData;
|
||||||
private final Object missingValue;
|
private final Object missingValue;
|
||||||
|
private final SortMode sortMode;
|
||||||
|
|
||||||
public DoubleValuesComparatorSource(IndexNumericFieldData<?> indexFieldData, @Nullable Object missingValue) {
|
public DoubleValuesComparatorSource(IndexNumericFieldData<?> indexFieldData, @Nullable Object missingValue, SortMode sortMode) {
|
||||||
this.indexFieldData = indexFieldData;
|
this.indexFieldData = indexFieldData;
|
||||||
this.missingValue = missingValue;
|
this.missingValue = missingValue;
|
||||||
|
this.sortMode = sortMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -57,6 +59,6 @@ public class DoubleValuesComparatorSource extends IndexFieldData.XFieldComparato
|
|||||||
dMissingValue = missingValue instanceof Number ? ((Number) missingValue).doubleValue() : Double.parseDouble(missingValue.toString());
|
dMissingValue = missingValue instanceof Number ? ((Number) missingValue).doubleValue() : Double.parseDouble(missingValue.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
return new DoubleValuesComparator(indexFieldData, dMissingValue, numHits, reversed);
|
return new DoubleValuesComparator(indexFieldData, dMissingValue, numHits, sortMode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,18 +19,18 @@
|
|||||||
|
|
||||||
package org.elasticsearch.index.fielddata.fieldcomparator;
|
package org.elasticsearch.index.fielddata.fieldcomparator;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import org.elasticsearch.index.fielddata.IndexNumericFieldData;
|
import org.elasticsearch.index.fielddata.IndexNumericFieldData;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
public final class FloatValuesComparator extends DoubleValuesComparatorBase<Float> {
|
public final class FloatValuesComparator extends DoubleValuesComparatorBase<Float> {
|
||||||
|
|
||||||
private final float[] values;
|
private final float[] values;
|
||||||
|
|
||||||
public FloatValuesComparator(IndexNumericFieldData<?> indexFieldData, float missingValue, int numHits, boolean reversed) {
|
public FloatValuesComparator(IndexNumericFieldData<?> indexFieldData, float missingValue, int numHits, SortMode sortMode) {
|
||||||
super(indexFieldData, missingValue, reversed);
|
super(indexFieldData, missingValue, sortMode);
|
||||||
assert indexFieldData.getNumericType().requiredBits() <= 32;
|
assert indexFieldData.getNumericType().requiredBits() <= 32;
|
||||||
this.values = new float[numHits];
|
this.values = new float[numHits];
|
||||||
}
|
}
|
||||||
|
@ -33,10 +33,12 @@ public class FloatValuesComparatorSource extends IndexFieldData.XFieldComparator
|
|||||||
|
|
||||||
private final IndexNumericFieldData<?> indexFieldData;
|
private final IndexNumericFieldData<?> indexFieldData;
|
||||||
private final Object missingValue;
|
private final Object missingValue;
|
||||||
|
private final SortMode sortMode;
|
||||||
|
|
||||||
public FloatValuesComparatorSource(IndexNumericFieldData<?> indexFieldData, @Nullable Object missingValue) {
|
public FloatValuesComparatorSource(IndexNumericFieldData<?> indexFieldData, @Nullable Object missingValue, SortMode sortMode) {
|
||||||
this.indexFieldData = indexFieldData;
|
this.indexFieldData = indexFieldData;
|
||||||
this.missingValue = missingValue;
|
this.missingValue = missingValue;
|
||||||
|
this.sortMode = sortMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -57,6 +59,6 @@ public class FloatValuesComparatorSource extends IndexFieldData.XFieldComparator
|
|||||||
dMissingValue = missingValue instanceof Number ? ((Number) missingValue).floatValue() : Float.parseFloat(missingValue.toString());
|
dMissingValue = missingValue instanceof Number ? ((Number) missingValue).floatValue() : Float.parseFloat(missingValue.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
return new FloatValuesComparator(indexFieldData, dMissingValue, numHits, reversed);
|
return new FloatValuesComparator(indexFieldData, dMissingValue, numHits, sortMode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,18 +19,18 @@
|
|||||||
|
|
||||||
package org.elasticsearch.index.fielddata.fieldcomparator;
|
package org.elasticsearch.index.fielddata.fieldcomparator;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import org.elasticsearch.index.fielddata.IndexNumericFieldData;
|
import org.elasticsearch.index.fielddata.IndexNumericFieldData;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
public final class IntValuesComparator extends LongValuesComparatorBase<Integer> {
|
public final class IntValuesComparator extends LongValuesComparatorBase<Integer> {
|
||||||
|
|
||||||
private final int[] values;
|
private final int[] values;
|
||||||
|
|
||||||
public IntValuesComparator(IndexNumericFieldData<?> indexFieldData, int missingValue, int numHits, boolean reversed) {
|
public IntValuesComparator(IndexNumericFieldData<?> indexFieldData, int missingValue, int numHits, SortMode sortMode) {
|
||||||
super(indexFieldData, missingValue, reversed);
|
super(indexFieldData, missingValue, sortMode);
|
||||||
assert indexFieldData.getNumericType().requiredBits() <= 32;
|
assert indexFieldData.getNumericType().requiredBits() <= 32;
|
||||||
this.values = new int[numHits];
|
this.values = new int[numHits];
|
||||||
}
|
}
|
||||||
|
@ -33,10 +33,12 @@ public class IntValuesComparatorSource extends IndexFieldData.XFieldComparatorSo
|
|||||||
|
|
||||||
private final IndexNumericFieldData<?> indexFieldData;
|
private final IndexNumericFieldData<?> indexFieldData;
|
||||||
private final Object missingValue;
|
private final Object missingValue;
|
||||||
|
private final SortMode sortMode;
|
||||||
|
|
||||||
public IntValuesComparatorSource(IndexNumericFieldData<?> indexFieldData, @Nullable Object missingValue) {
|
public IntValuesComparatorSource(IndexNumericFieldData<?> indexFieldData, @Nullable Object missingValue, SortMode sortMode) {
|
||||||
this.indexFieldData = indexFieldData;
|
this.indexFieldData = indexFieldData;
|
||||||
this.missingValue = missingValue;
|
this.missingValue = missingValue;
|
||||||
|
this.sortMode = sortMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -57,6 +59,6 @@ public class IntValuesComparatorSource extends IndexFieldData.XFieldComparatorSo
|
|||||||
dMissingValue = missingValue instanceof Number ? ((Number) missingValue).intValue() : Integer.parseInt(missingValue.toString());
|
dMissingValue = missingValue instanceof Number ? ((Number) missingValue).intValue() : Integer.parseInt(missingValue.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
return new IntValuesComparator(indexFieldData, dMissingValue, numHits, reversed);
|
return new IntValuesComparator(indexFieldData, dMissingValue, numHits, sortMode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,18 +19,18 @@
|
|||||||
|
|
||||||
package org.elasticsearch.index.fielddata.fieldcomparator;
|
package org.elasticsearch.index.fielddata.fieldcomparator;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import org.elasticsearch.index.fielddata.IndexNumericFieldData;
|
import org.elasticsearch.index.fielddata.IndexNumericFieldData;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
public final class LongValuesComparator extends LongValuesComparatorBase<Long> {
|
public final class LongValuesComparator extends LongValuesComparatorBase<Long> {
|
||||||
|
|
||||||
private final long[] values;
|
private final long[] values;
|
||||||
|
|
||||||
public LongValuesComparator(IndexNumericFieldData<?> indexFieldData, long missingValue, int numHits, boolean reversed) {
|
public LongValuesComparator(IndexNumericFieldData<?> indexFieldData, long missingValue, int numHits, SortMode sortMode) {
|
||||||
super(indexFieldData, missingValue, reversed);
|
super(indexFieldData, missingValue, sortMode);
|
||||||
this.values = new long[numHits];
|
this.values = new long[numHits];
|
||||||
assert indexFieldData.getNumericType().requiredBits() <= 64;
|
assert indexFieldData.getNumericType().requiredBits() <= 64;
|
||||||
}
|
}
|
||||||
@ -50,7 +50,7 @@ public final class LongValuesComparator extends LongValuesComparatorBase<Long> {
|
|||||||
public void copy(int slot, int doc) throws IOException {
|
public void copy(int slot, int doc) throws IOException {
|
||||||
values[slot] = readerValues.getValueMissing(doc, missingValue);
|
values[slot] = readerValues.getValueMissing(doc, missingValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long value(int slot) {
|
public Long value(int slot) {
|
||||||
return Long.valueOf(values[slot]);
|
return Long.valueOf(values[slot]);
|
||||||
|
@ -17,26 +17,27 @@ package org.elasticsearch.index.fielddata.fieldcomparator;
|
|||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import org.apache.lucene.index.AtomicReaderContext;
|
import org.apache.lucene.index.AtomicReaderContext;
|
||||||
import org.apache.lucene.search.FieldComparator;
|
import org.apache.lucene.search.FieldComparator;
|
||||||
import org.elasticsearch.index.fielddata.IndexNumericFieldData;
|
import org.elasticsearch.index.fielddata.IndexNumericFieldData;
|
||||||
import org.elasticsearch.index.fielddata.LongValues;
|
import org.elasticsearch.index.fielddata.LongValues;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
abstract class LongValuesComparatorBase<T extends Number> extends FieldComparator<T> {
|
abstract class LongValuesComparatorBase<T extends Number> extends FieldComparator<T> {
|
||||||
|
|
||||||
protected final IndexNumericFieldData<?> indexFieldData;
|
protected final IndexNumericFieldData<?> indexFieldData;
|
||||||
private final boolean reversed;
|
|
||||||
protected final long missingValue;
|
protected final long missingValue;
|
||||||
protected long bottom;
|
protected long bottom;
|
||||||
protected LongValues readerValues;
|
protected LongValues readerValues;
|
||||||
|
private final SortMode sortMode;
|
||||||
|
|
||||||
public LongValuesComparatorBase(IndexNumericFieldData<?> indexFieldData, long missingValue, boolean reversed) {
|
|
||||||
|
public LongValuesComparatorBase(IndexNumericFieldData<?> indexFieldData, long missingValue, SortMode sortMode) {
|
||||||
this.indexFieldData = indexFieldData;
|
this.indexFieldData = indexFieldData;
|
||||||
this.missingValue = missingValue;
|
this.missingValue = missingValue;
|
||||||
this.reversed = reversed;
|
this.sortMode = sortMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -44,14 +45,14 @@ abstract class LongValuesComparatorBase<T extends Number> extends FieldComparato
|
|||||||
long v2 = readerValues.getValueMissing(doc, missingValue);
|
long v2 = readerValues.getValueMissing(doc, missingValue);
|
||||||
return compare(bottom, v2);
|
return compare(bottom, v2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final int compareDocToValue(int doc, T valueObj) throws IOException {
|
public final int compareDocToValue(int doc, T valueObj) throws IOException {
|
||||||
final long value = valueObj.longValue();
|
final long value = valueObj.longValue();
|
||||||
long docValue = readerValues.getValueMissing(doc, missingValue);
|
long docValue = readerValues.getValueMissing(doc, missingValue);
|
||||||
return compare(docValue, value);
|
return compare(docValue, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
static final int compare(long left, long right) {
|
static final int compare(long left, long right) {
|
||||||
if (left > right) {
|
if (left > right) {
|
||||||
return 1;
|
return 1;
|
||||||
@ -61,23 +62,23 @@ abstract class LongValuesComparatorBase<T extends Number> extends FieldComparato
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final FieldComparator<T> setNextReader(AtomicReaderContext context) throws IOException {
|
public final FieldComparator<T> setNextReader(AtomicReaderContext context) throws IOException {
|
||||||
readerValues = indexFieldData.load(context).getLongValues();
|
readerValues = indexFieldData.load(context).getLongValues();
|
||||||
if (readerValues.isMultiValued()) {
|
if (readerValues.isMultiValued()) {
|
||||||
readerValues = new MultiValuedBytesWrapper(readerValues, reversed);
|
readerValues = new MultiValuedBytesWrapper(readerValues, sortMode);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class MultiValuedBytesWrapper extends LongValues.FilteredLongValues {
|
private static final class MultiValuedBytesWrapper extends LongValues.FilteredLongValues {
|
||||||
|
|
||||||
private final boolean reversed;
|
private final SortMode sortMode;
|
||||||
|
|
||||||
public MultiValuedBytesWrapper(LongValues delegate, boolean reversed) {
|
public MultiValuedBytesWrapper(LongValues delegate, SortMode sortMode) {
|
||||||
super(delegate);
|
super(delegate);
|
||||||
this.reversed = reversed;
|
this.sortMode = sortMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -89,22 +90,33 @@ abstract class LongValuesComparatorBase<T extends Number> extends FieldComparato
|
|||||||
|
|
||||||
long currentVal = iter.next();
|
long currentVal = iter.next();
|
||||||
long relevantVal = currentVal;
|
long relevantVal = currentVal;
|
||||||
while (true) {
|
int counter = 1;
|
||||||
if (reversed) {
|
while (iter.hasNext()) {
|
||||||
if (currentVal > relevantVal) {
|
|
||||||
relevantVal = currentVal;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (currentVal < relevantVal) {
|
|
||||||
relevantVal = currentVal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!iter.hasNext()) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
currentVal = iter.next();
|
currentVal = iter.next();
|
||||||
|
switch (sortMode) {
|
||||||
|
case SUM:
|
||||||
|
relevantVal += currentVal;
|
||||||
|
break;
|
||||||
|
case AVG:
|
||||||
|
relevantVal += currentVal;
|
||||||
|
counter++;
|
||||||
|
break;
|
||||||
|
case MAX:
|
||||||
|
if (currentVal > relevantVal) {
|
||||||
|
relevantVal = currentVal;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MIN:
|
||||||
|
if (currentVal < relevantVal) {
|
||||||
|
relevantVal = currentVal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sortMode == SortMode.AVG) {
|
||||||
|
return relevantVal / counter;
|
||||||
|
} else {
|
||||||
|
return relevantVal;
|
||||||
}
|
}
|
||||||
return relevantVal;
|
|
||||||
// If we have a method on readerValues that tells if the values emitted by Iter or ArrayRef are sorted per
|
// If we have a method on readerValues that tells if the values emitted by Iter or ArrayRef are sorted per
|
||||||
// document that we can do this or something similar:
|
// document that we can do this or something similar:
|
||||||
// (This is already possible, if values are loaded from index, but we just need a method that tells us this
|
// (This is already possible, if values are loaded from index, but we just need a method that tells us this
|
||||||
|
@ -33,10 +33,12 @@ public class LongValuesComparatorSource extends IndexFieldData.XFieldComparatorS
|
|||||||
|
|
||||||
private final IndexNumericFieldData<?> indexFieldData;
|
private final IndexNumericFieldData<?> indexFieldData;
|
||||||
private final Object missingValue;
|
private final Object missingValue;
|
||||||
|
private final SortMode sortMode;
|
||||||
|
|
||||||
public LongValuesComparatorSource(IndexNumericFieldData<?> indexFieldData, @Nullable Object missingValue) {
|
public LongValuesComparatorSource(IndexNumericFieldData<?> indexFieldData, @Nullable Object missingValue, SortMode sortMode) {
|
||||||
this.indexFieldData = indexFieldData;
|
this.indexFieldData = indexFieldData;
|
||||||
this.missingValue = missingValue;
|
this.missingValue = missingValue;
|
||||||
|
this.sortMode = sortMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -57,6 +59,6 @@ public class LongValuesComparatorSource extends IndexFieldData.XFieldComparatorS
|
|||||||
dMissingValue = missingValue instanceof Number ? ((Number) missingValue).longValue() : Long.parseLong(missingValue.toString());
|
dMissingValue = missingValue instanceof Number ? ((Number) missingValue).longValue() : Long.parseLong(missingValue.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
return new LongValuesComparator(indexFieldData, dMissingValue, numHits, reversed);
|
return new LongValuesComparator(indexFieldData, dMissingValue, numHits, sortMode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,27 +19,29 @@
|
|||||||
|
|
||||||
package org.elasticsearch.index.fielddata.fieldcomparator;
|
package org.elasticsearch.index.fielddata.fieldcomparator;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import org.elasticsearch.index.fielddata.IndexNumericFieldData;
|
import org.elasticsearch.index.fielddata.IndexNumericFieldData;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
public final class ShortValuesComparator extends LongValuesComparatorBase<Short> {
|
public final class ShortValuesComparator extends LongValuesComparatorBase<Short> {
|
||||||
|
|
||||||
private final short[] values;
|
private final short[] values;
|
||||||
|
private final SortMode sortMode;
|
||||||
|
|
||||||
public ShortValuesComparator(IndexNumericFieldData<?> indexFieldData, short missingValue, int numHits, boolean reversed) {
|
public ShortValuesComparator(IndexNumericFieldData<?> indexFieldData, short missingValue, int numHits, SortMode sortMode) {
|
||||||
super(indexFieldData, missingValue, reversed);
|
super(indexFieldData, missingValue, sortMode);
|
||||||
assert indexFieldData.getNumericType().requiredBits() <= 16;
|
assert indexFieldData.getNumericType().requiredBits() <= 16;
|
||||||
this.values = new short[numHits];
|
this.values = new short[numHits];
|
||||||
|
this.sortMode = sortMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compare(int slot1, int slot2) {
|
public int compare(int slot1, int slot2) {
|
||||||
final int v1 = values[slot1];
|
final int v1 = values[slot1];
|
||||||
final int v2 = values[slot2];
|
final int v2 = values[slot2];
|
||||||
return v1-v2; // we cast to int so it can't overflow
|
return v1 - v2; // we cast to int so it can't overflow
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -33,10 +33,12 @@ public class ShortValuesComparatorSource extends IndexFieldData.XFieldComparator
|
|||||||
|
|
||||||
private final IndexNumericFieldData<?> indexFieldData;
|
private final IndexNumericFieldData<?> indexFieldData;
|
||||||
private final Object missingValue;
|
private final Object missingValue;
|
||||||
|
private final SortMode sortMode;
|
||||||
|
|
||||||
public ShortValuesComparatorSource(IndexNumericFieldData<?> indexFieldData, @Nullable Object missingValue) {
|
public ShortValuesComparatorSource(IndexNumericFieldData<?> indexFieldData, @Nullable Object missingValue, SortMode sortMode) {
|
||||||
this.indexFieldData = indexFieldData;
|
this.indexFieldData = indexFieldData;
|
||||||
this.missingValue = missingValue;
|
this.missingValue = missingValue;
|
||||||
|
this.sortMode = sortMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -57,6 +59,6 @@ public class ShortValuesComparatorSource extends IndexFieldData.XFieldComparator
|
|||||||
dMissingValue = missingValue instanceof Number ? ((Number) missingValue).shortValue() : Short.parseShort(missingValue.toString());
|
dMissingValue = missingValue instanceof Number ? ((Number) missingValue).shortValue() : Short.parseShort(missingValue.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ShortValuesComparator(indexFieldData, dMissingValue, numHits, reversed);
|
return new ShortValuesComparator(indexFieldData, dMissingValue, numHits, sortMode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to ElasticSearch and Shay Banon under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. ElasticSearch licenses this
|
||||||
|
* file to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
package org.elasticsearch.index.fielddata.fieldcomparator;
|
||||||
|
|
||||||
|
import org.elasticsearch.ElasticSearchIllegalArgumentException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines what values to pick in the case a document contains multiple values for a particular field.
|
||||||
|
*/
|
||||||
|
public enum SortMode {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sum of all the values.
|
||||||
|
*/
|
||||||
|
SUM,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Average of all the values.
|
||||||
|
*/
|
||||||
|
AVG,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pick the lowest value.
|
||||||
|
*/
|
||||||
|
MIN,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pick the highest value.
|
||||||
|
*/
|
||||||
|
MAX;
|
||||||
|
|
||||||
|
public static SortMode fromString(String sortMode) {
|
||||||
|
if ("min".equals(sortMode)) {
|
||||||
|
return MIN;
|
||||||
|
} else if ("max".equals(sortMode)) {
|
||||||
|
return MAX;
|
||||||
|
} else if ("sum".equals(sortMode)) {
|
||||||
|
return SUM;
|
||||||
|
} else if ("avg".equals(sortMode)) {
|
||||||
|
return AVG;
|
||||||
|
} else {
|
||||||
|
throw new ElasticSearchIllegalArgumentException("Illegal sort_mode " + sortMode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -20,9 +20,9 @@
|
|||||||
package org.elasticsearch.index.fielddata.plain;
|
package org.elasticsearch.index.fielddata.plain;
|
||||||
|
|
||||||
import gnu.trove.list.array.TByteArrayList;
|
import gnu.trove.list.array.TByteArrayList;
|
||||||
import org.apache.lucene.index.*;
|
import org.apache.lucene.index.AtomicReader;
|
||||||
import org.apache.lucene.search.FieldCache;
|
import org.apache.lucene.index.AtomicReaderContext;
|
||||||
import org.apache.lucene.search.FieldCache.StopFillCacheException;
|
import org.apache.lucene.index.Terms;
|
||||||
import org.apache.lucene.util.BytesRef;
|
import org.apache.lucene.util.BytesRef;
|
||||||
import org.apache.lucene.util.BytesRefIterator;
|
import org.apache.lucene.util.BytesRefIterator;
|
||||||
import org.apache.lucene.util.FixedBitSet;
|
import org.apache.lucene.util.FixedBitSet;
|
||||||
@ -33,14 +33,13 @@ import org.elasticsearch.common.settings.Settings;
|
|||||||
import org.elasticsearch.index.Index;
|
import org.elasticsearch.index.Index;
|
||||||
import org.elasticsearch.index.fielddata.*;
|
import org.elasticsearch.index.fielddata.*;
|
||||||
import org.elasticsearch.index.fielddata.fieldcomparator.ByteValuesComparatorSource;
|
import org.elasticsearch.index.fielddata.fieldcomparator.ByteValuesComparatorSource;
|
||||||
|
import org.elasticsearch.index.fielddata.fieldcomparator.SortMode;
|
||||||
import org.elasticsearch.index.fielddata.ordinals.Ordinals;
|
import org.elasticsearch.index.fielddata.ordinals.Ordinals;
|
||||||
import org.elasticsearch.index.fielddata.ordinals.Ordinals.Docs;
|
import org.elasticsearch.index.fielddata.ordinals.Ordinals.Docs;
|
||||||
import org.elasticsearch.index.fielddata.ordinals.OrdinalsBuilder;
|
import org.elasticsearch.index.fielddata.ordinals.OrdinalsBuilder;
|
||||||
import org.elasticsearch.index.mapper.FieldMapper;
|
import org.elasticsearch.index.mapper.FieldMapper;
|
||||||
import org.elasticsearch.index.settings.IndexSettings;
|
import org.elasticsearch.index.settings.IndexSettings;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
public class ByteArrayIndexFieldData extends AbstractIndexFieldData<ByteArrayAtomicFieldData> implements IndexNumericFieldData<ByteArrayAtomicFieldData> {
|
public class ByteArrayIndexFieldData extends AbstractIndexFieldData<ByteArrayAtomicFieldData> implements IndexNumericFieldData<ByteArrayAtomicFieldData> {
|
||||||
@ -96,8 +95,8 @@ public class ByteArrayIndexFieldData extends AbstractIndexFieldData<ByteArrayAto
|
|||||||
OrdinalsBuilder builder = new OrdinalsBuilder(terms, reader.maxDoc());
|
OrdinalsBuilder builder = new OrdinalsBuilder(terms, reader.maxDoc());
|
||||||
BytesRefIterator iter = builder.buildFromTerms(builder.wrapNumeric32Bit(terms.iterator(null)), reader.getLiveDocs());
|
BytesRefIterator iter = builder.buildFromTerms(builder.wrapNumeric32Bit(terms.iterator(null)), reader.getLiveDocs());
|
||||||
BytesRef term;
|
BytesRef term;
|
||||||
while((term = iter.next()) != null) {
|
while ((term = iter.next()) != null) {
|
||||||
values.add((byte) NumericUtils.prefixCodedToInt(term));
|
values.add((byte) NumericUtils.prefixCodedToInt(term));
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
Ordinals build = builder.build(fieldDataType.getSettings());
|
Ordinals build = builder.build(fieldDataType.getSettings());
|
||||||
@ -106,7 +105,7 @@ public class ByteArrayIndexFieldData extends AbstractIndexFieldData<ByteArrayAto
|
|||||||
byte[] sValues = new byte[reader.maxDoc()];
|
byte[] sValues = new byte[reader.maxDoc()];
|
||||||
int maxDoc = reader.maxDoc();
|
int maxDoc = reader.maxDoc();
|
||||||
for (int i = 0; i < maxDoc; i++) {
|
for (int i = 0; i < maxDoc; i++) {
|
||||||
sValues[i] = values.get(ordinals.getOrd(i));
|
sValues[i] = values.get(ordinals.getOrd(i));
|
||||||
}
|
}
|
||||||
final FixedBitSet set = builder.buildDocsWithValuesSet();
|
final FixedBitSet set = builder.buildDocsWithValuesSet();
|
||||||
if (set == null) {
|
if (set == null) {
|
||||||
@ -126,7 +125,7 @@ public class ByteArrayIndexFieldData extends AbstractIndexFieldData<ByteArrayAto
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public XFieldComparatorSource comparatorSource(@Nullable Object missingValue) {
|
public XFieldComparatorSource comparatorSource(@Nullable Object missingValue, SortMode sortMode) {
|
||||||
return new ByteValuesComparatorSource(this, missingValue);
|
return new ByteValuesComparatorSource(this, missingValue, sortMode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,9 +19,9 @@
|
|||||||
|
|
||||||
package org.elasticsearch.index.fielddata.plain;
|
package org.elasticsearch.index.fielddata.plain;
|
||||||
|
|
||||||
import org.apache.lucene.index.*;
|
import org.apache.lucene.index.AtomicReader;
|
||||||
import org.apache.lucene.search.FieldCache;
|
import org.apache.lucene.index.AtomicReaderContext;
|
||||||
import org.apache.lucene.search.FieldCache.StopFillCacheException;
|
import org.apache.lucene.index.Terms;
|
||||||
import org.apache.lucene.util.BytesRef;
|
import org.apache.lucene.util.BytesRef;
|
||||||
import org.apache.lucene.util.BytesRefIterator;
|
import org.apache.lucene.util.BytesRefIterator;
|
||||||
import org.elasticsearch.ElasticSearchException;
|
import org.elasticsearch.ElasticSearchException;
|
||||||
@ -33,9 +33,8 @@ import org.elasticsearch.index.fielddata.FieldDataType;
|
|||||||
import org.elasticsearch.index.fielddata.IndexFieldData;
|
import org.elasticsearch.index.fielddata.IndexFieldData;
|
||||||
import org.elasticsearch.index.fielddata.IndexFieldDataCache;
|
import org.elasticsearch.index.fielddata.IndexFieldDataCache;
|
||||||
import org.elasticsearch.index.fielddata.fieldcomparator.BytesRefFieldComparatorSource;
|
import org.elasticsearch.index.fielddata.fieldcomparator.BytesRefFieldComparatorSource;
|
||||||
import org.elasticsearch.index.fielddata.ordinals.Ordinals;
|
import org.elasticsearch.index.fielddata.fieldcomparator.SortMode;
|
||||||
import org.elasticsearch.index.fielddata.ordinals.OrdinalsBuilder;
|
import org.elasticsearch.index.fielddata.ordinals.OrdinalsBuilder;
|
||||||
import org.elasticsearch.index.fielddata.ordinals.SingleArrayOrdinals;
|
|
||||||
import org.elasticsearch.index.mapper.FieldMapper;
|
import org.elasticsearch.index.mapper.FieldMapper;
|
||||||
import org.elasticsearch.index.settings.IndexSettings;
|
import org.elasticsearch.index.settings.IndexSettings;
|
||||||
|
|
||||||
@ -94,7 +93,7 @@ public class ConcreteBytesRefIndexFieldData extends AbstractIndexFieldData<Concr
|
|||||||
try {
|
try {
|
||||||
BytesRefIterator iter = builder.buildFromTerms(terms.iterator(null), reader.getLiveDocs());
|
BytesRefIterator iter = builder.buildFromTerms(terms.iterator(null), reader.getLiveDocs());
|
||||||
BytesRef term;
|
BytesRef term;
|
||||||
while((term = iter.next()) != null) {
|
while ((term = iter.next()) != null) {
|
||||||
values.add(BytesRef.deepCopyOf(term));
|
values.add(BytesRef.deepCopyOf(term));
|
||||||
}
|
}
|
||||||
return new ConcreteBytesRefAtomicFieldData(values.toArray(new BytesRef[values.size()]), builder.build(fieldDataType.getSettings()));
|
return new ConcreteBytesRefAtomicFieldData(values.toArray(new BytesRef[values.size()]), builder.build(fieldDataType.getSettings()));
|
||||||
@ -104,8 +103,8 @@ public class ConcreteBytesRefIndexFieldData extends AbstractIndexFieldData<Concr
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public XFieldComparatorSource comparatorSource(@Nullable Object missingValue) {
|
public XFieldComparatorSource comparatorSource(@Nullable Object missingValue, SortMode sortMode) {
|
||||||
// TODO support "missingValue" for sortMissingValue options here...
|
// TODO support "missingValue" for sortMissingValue options here...
|
||||||
return new BytesRefFieldComparatorSource(this);
|
return new BytesRefFieldComparatorSource(this, sortMode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,9 +20,9 @@
|
|||||||
package org.elasticsearch.index.fielddata.plain;
|
package org.elasticsearch.index.fielddata.plain;
|
||||||
|
|
||||||
import gnu.trove.list.array.TDoubleArrayList;
|
import gnu.trove.list.array.TDoubleArrayList;
|
||||||
import org.apache.lucene.index.*;
|
import org.apache.lucene.index.AtomicReader;
|
||||||
import org.apache.lucene.search.FieldCache;
|
import org.apache.lucene.index.AtomicReaderContext;
|
||||||
import org.apache.lucene.search.FieldCache.StopFillCacheException;
|
import org.apache.lucene.index.Terms;
|
||||||
import org.apache.lucene.util.BytesRef;
|
import org.apache.lucene.util.BytesRef;
|
||||||
import org.apache.lucene.util.BytesRefIterator;
|
import org.apache.lucene.util.BytesRefIterator;
|
||||||
import org.apache.lucene.util.FixedBitSet;
|
import org.apache.lucene.util.FixedBitSet;
|
||||||
@ -33,9 +33,10 @@ import org.elasticsearch.common.settings.Settings;
|
|||||||
import org.elasticsearch.index.Index;
|
import org.elasticsearch.index.Index;
|
||||||
import org.elasticsearch.index.fielddata.*;
|
import org.elasticsearch.index.fielddata.*;
|
||||||
import org.elasticsearch.index.fielddata.fieldcomparator.DoubleValuesComparatorSource;
|
import org.elasticsearch.index.fielddata.fieldcomparator.DoubleValuesComparatorSource;
|
||||||
|
import org.elasticsearch.index.fielddata.fieldcomparator.SortMode;
|
||||||
import org.elasticsearch.index.fielddata.ordinals.Ordinals;
|
import org.elasticsearch.index.fielddata.ordinals.Ordinals;
|
||||||
import org.elasticsearch.index.fielddata.ordinals.OrdinalsBuilder;
|
|
||||||
import org.elasticsearch.index.fielddata.ordinals.Ordinals.Docs;
|
import org.elasticsearch.index.fielddata.ordinals.Ordinals.Docs;
|
||||||
|
import org.elasticsearch.index.fielddata.ordinals.OrdinalsBuilder;
|
||||||
import org.elasticsearch.index.mapper.FieldMapper;
|
import org.elasticsearch.index.mapper.FieldMapper;
|
||||||
import org.elasticsearch.index.settings.IndexSettings;
|
import org.elasticsearch.index.settings.IndexSettings;
|
||||||
|
|
||||||
@ -82,7 +83,7 @@ public class DoubleArrayIndexFieldData extends AbstractIndexFieldData<DoubleArra
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DoubleArrayAtomicFieldData loadDirect(AtomicReaderContext context) throws Exception {
|
public DoubleArrayAtomicFieldData loadDirect(AtomicReaderContext context) throws Exception {
|
||||||
|
|
||||||
AtomicReader reader = context.reader();
|
AtomicReader reader = context.reader();
|
||||||
Terms terms = reader.terms(getFieldNames().indexName());
|
Terms terms = reader.terms(getFieldNames().indexName());
|
||||||
if (terms == null) {
|
if (terms == null) {
|
||||||
@ -96,7 +97,7 @@ public class DoubleArrayIndexFieldData extends AbstractIndexFieldData<DoubleArra
|
|||||||
try {
|
try {
|
||||||
final BytesRefIterator iter = builder.buildFromTerms(builder.wrapNumeric64Bit(terms.iterator(null)), reader.getLiveDocs());
|
final BytesRefIterator iter = builder.buildFromTerms(builder.wrapNumeric64Bit(terms.iterator(null)), reader.getLiveDocs());
|
||||||
BytesRef term;
|
BytesRef term;
|
||||||
while((term = iter.next()) != null) {
|
while ((term = iter.next()) != null) {
|
||||||
values.add(NumericUtils.sortableLongToDouble(NumericUtils.prefixCodedToLong(term)));
|
values.add(NumericUtils.sortableLongToDouble(NumericUtils.prefixCodedToLong(term)));
|
||||||
}
|
}
|
||||||
Ordinals build = builder.build(fieldDataType.getSettings());
|
Ordinals build = builder.build(fieldDataType.getSettings());
|
||||||
@ -105,7 +106,7 @@ public class DoubleArrayIndexFieldData extends AbstractIndexFieldData<DoubleArra
|
|||||||
double[] sValues = new double[reader.maxDoc()];
|
double[] sValues = new double[reader.maxDoc()];
|
||||||
int maxDoc = reader.maxDoc();
|
int maxDoc = reader.maxDoc();
|
||||||
for (int i = 0; i < maxDoc; i++) {
|
for (int i = 0; i < maxDoc; i++) {
|
||||||
sValues[i] = values.get(ordinals.getOrd(i));
|
sValues[i] = values.get(ordinals.getOrd(i));
|
||||||
}
|
}
|
||||||
final FixedBitSet set = builder.buildDocsWithValuesSet();
|
final FixedBitSet set = builder.buildDocsWithValuesSet();
|
||||||
if (set == null) {
|
if (set == null) {
|
||||||
@ -122,11 +123,11 @@ public class DoubleArrayIndexFieldData extends AbstractIndexFieldData<DoubleArra
|
|||||||
} finally {
|
} finally {
|
||||||
builder.close();
|
builder.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public XFieldComparatorSource comparatorSource(@Nullable Object missingValue) {
|
public XFieldComparatorSource comparatorSource(@Nullable Object missingValue, SortMode sortMode) {
|
||||||
return new DoubleValuesComparatorSource(this, missingValue);
|
return new DoubleValuesComparatorSource(this, missingValue, sortMode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,9 +20,9 @@
|
|||||||
package org.elasticsearch.index.fielddata.plain;
|
package org.elasticsearch.index.fielddata.plain;
|
||||||
|
|
||||||
import gnu.trove.list.array.TFloatArrayList;
|
import gnu.trove.list.array.TFloatArrayList;
|
||||||
import org.apache.lucene.index.*;
|
import org.apache.lucene.index.AtomicReader;
|
||||||
import org.apache.lucene.search.FieldCache;
|
import org.apache.lucene.index.AtomicReaderContext;
|
||||||
import org.apache.lucene.search.FieldCache.StopFillCacheException;
|
import org.apache.lucene.index.Terms;
|
||||||
import org.apache.lucene.util.BytesRef;
|
import org.apache.lucene.util.BytesRef;
|
||||||
import org.apache.lucene.util.BytesRefIterator;
|
import org.apache.lucene.util.BytesRefIterator;
|
||||||
import org.apache.lucene.util.FixedBitSet;
|
import org.apache.lucene.util.FixedBitSet;
|
||||||
@ -33,9 +33,10 @@ import org.elasticsearch.common.settings.Settings;
|
|||||||
import org.elasticsearch.index.Index;
|
import org.elasticsearch.index.Index;
|
||||||
import org.elasticsearch.index.fielddata.*;
|
import org.elasticsearch.index.fielddata.*;
|
||||||
import org.elasticsearch.index.fielddata.fieldcomparator.FloatValuesComparatorSource;
|
import org.elasticsearch.index.fielddata.fieldcomparator.FloatValuesComparatorSource;
|
||||||
|
import org.elasticsearch.index.fielddata.fieldcomparator.SortMode;
|
||||||
import org.elasticsearch.index.fielddata.ordinals.Ordinals;
|
import org.elasticsearch.index.fielddata.ordinals.Ordinals;
|
||||||
import org.elasticsearch.index.fielddata.ordinals.OrdinalsBuilder;
|
|
||||||
import org.elasticsearch.index.fielddata.ordinals.Ordinals.Docs;
|
import org.elasticsearch.index.fielddata.ordinals.Ordinals.Docs;
|
||||||
|
import org.elasticsearch.index.fielddata.ordinals.OrdinalsBuilder;
|
||||||
import org.elasticsearch.index.mapper.FieldMapper;
|
import org.elasticsearch.index.mapper.FieldMapper;
|
||||||
import org.elasticsearch.index.settings.IndexSettings;
|
import org.elasticsearch.index.settings.IndexSettings;
|
||||||
|
|
||||||
@ -91,12 +92,12 @@ public class FloatArrayIndexFieldData extends AbstractIndexFieldData<FloatArrayA
|
|||||||
final TFloatArrayList values = new TFloatArrayList();
|
final TFloatArrayList values = new TFloatArrayList();
|
||||||
|
|
||||||
values.add(0); // first "t" indicates null value
|
values.add(0); // first "t" indicates null value
|
||||||
|
|
||||||
OrdinalsBuilder builder = new OrdinalsBuilder(terms, reader.maxDoc());
|
OrdinalsBuilder builder = new OrdinalsBuilder(terms, reader.maxDoc());
|
||||||
try {
|
try {
|
||||||
BytesRefIterator iter = builder.buildFromTerms(builder.wrapNumeric32Bit(terms.iterator(null)), reader.getLiveDocs());
|
BytesRefIterator iter = builder.buildFromTerms(builder.wrapNumeric32Bit(terms.iterator(null)), reader.getLiveDocs());
|
||||||
BytesRef term;
|
BytesRef term;
|
||||||
while((term = iter.next()) != null) {
|
while ((term = iter.next()) != null) {
|
||||||
values.add(NumericUtils.sortableIntToFloat(NumericUtils.prefixCodedToInt(term)));
|
values.add(NumericUtils.sortableIntToFloat(NumericUtils.prefixCodedToInt(term)));
|
||||||
}
|
}
|
||||||
Ordinals build = builder.build(fieldDataType.getSettings());
|
Ordinals build = builder.build(fieldDataType.getSettings());
|
||||||
@ -105,7 +106,7 @@ public class FloatArrayIndexFieldData extends AbstractIndexFieldData<FloatArrayA
|
|||||||
float[] sValues = new float[reader.maxDoc()];
|
float[] sValues = new float[reader.maxDoc()];
|
||||||
int maxDoc = reader.maxDoc();
|
int maxDoc = reader.maxDoc();
|
||||||
for (int i = 0; i < maxDoc; i++) {
|
for (int i = 0; i < maxDoc; i++) {
|
||||||
sValues[i] = values.get(ordinals.getOrd(i));
|
sValues[i] = values.get(ordinals.getOrd(i));
|
||||||
}
|
}
|
||||||
final FixedBitSet set = builder.buildDocsWithValuesSet();
|
final FixedBitSet set = builder.buildDocsWithValuesSet();
|
||||||
if (set == null) {
|
if (set == null) {
|
||||||
@ -126,7 +127,7 @@ public class FloatArrayIndexFieldData extends AbstractIndexFieldData<FloatArrayA
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public XFieldComparatorSource comparatorSource(@Nullable Object missingValue) {
|
public XFieldComparatorSource comparatorSource(@Nullable Object missingValue, SortMode sortMode) {
|
||||||
return new FloatValuesComparatorSource(this, missingValue);
|
return new FloatValuesComparatorSource(this, missingValue, sortMode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,23 +20,20 @@
|
|||||||
package org.elasticsearch.index.fielddata.plain;
|
package org.elasticsearch.index.fielddata.plain;
|
||||||
|
|
||||||
import gnu.trove.list.array.TDoubleArrayList;
|
import gnu.trove.list.array.TDoubleArrayList;
|
||||||
import org.apache.lucene.index.*;
|
import org.apache.lucene.index.AtomicReader;
|
||||||
import org.apache.lucene.search.FieldCache;
|
import org.apache.lucene.index.AtomicReaderContext;
|
||||||
import org.apache.lucene.search.FieldCache.StopFillCacheException;
|
import org.apache.lucene.index.Terms;
|
||||||
import org.apache.lucene.util.BytesRef;
|
import org.apache.lucene.util.*;
|
||||||
import org.apache.lucene.util.BytesRefIterator;
|
|
||||||
import org.apache.lucene.util.CharsRef;
|
|
||||||
import org.apache.lucene.util.FixedBitSet;
|
|
||||||
import org.apache.lucene.util.UnicodeUtil;
|
|
||||||
import org.elasticsearch.ElasticSearchException;
|
import org.elasticsearch.ElasticSearchException;
|
||||||
import org.elasticsearch.ElasticSearchIllegalArgumentException;
|
import org.elasticsearch.ElasticSearchIllegalArgumentException;
|
||||||
import org.elasticsearch.common.Nullable;
|
import org.elasticsearch.common.Nullable;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.index.Index;
|
import org.elasticsearch.index.Index;
|
||||||
import org.elasticsearch.index.fielddata.*;
|
import org.elasticsearch.index.fielddata.*;
|
||||||
|
import org.elasticsearch.index.fielddata.fieldcomparator.SortMode;
|
||||||
import org.elasticsearch.index.fielddata.ordinals.Ordinals;
|
import org.elasticsearch.index.fielddata.ordinals.Ordinals;
|
||||||
import org.elasticsearch.index.fielddata.ordinals.OrdinalsBuilder;
|
|
||||||
import org.elasticsearch.index.fielddata.ordinals.Ordinals.Docs;
|
import org.elasticsearch.index.fielddata.ordinals.Ordinals.Docs;
|
||||||
|
import org.elasticsearch.index.fielddata.ordinals.OrdinalsBuilder;
|
||||||
import org.elasticsearch.index.mapper.FieldMapper;
|
import org.elasticsearch.index.mapper.FieldMapper;
|
||||||
import org.elasticsearch.index.settings.IndexSettings;
|
import org.elasticsearch.index.settings.IndexSettings;
|
||||||
|
|
||||||
@ -94,20 +91,20 @@ public class GeoPointDoubleArrayIndexFieldData extends AbstractIndexFieldData<Ge
|
|||||||
try {
|
try {
|
||||||
BytesRefIterator iter = builder.buildFromTerms(terms.iterator(null), reader.getLiveDocs());
|
BytesRefIterator iter = builder.buildFromTerms(terms.iterator(null), reader.getLiveDocs());
|
||||||
BytesRef term;
|
BytesRef term;
|
||||||
while((term = iter.next()) != null) {
|
while ((term = iter.next()) != null) {
|
||||||
UnicodeUtil.UTF8toUTF16(term, spare);
|
UnicodeUtil.UTF8toUTF16(term, spare);
|
||||||
boolean parsed = false;
|
boolean parsed = false;
|
||||||
for (int i = spare.offset; i < spare.length; i++) {
|
for (int i = spare.offset; i < spare.length; i++) {
|
||||||
if (spare.chars[i] == ',') { // safes a string creation
|
if (spare.chars[i] == ',') { // safes a string creation
|
||||||
lat.add(Double.parseDouble(new String(spare.chars, spare.offset, (i - spare.offset))));
|
lat.add(Double.parseDouble(new String(spare.chars, spare.offset, (i - spare.offset))));
|
||||||
lon.add(Double.parseDouble(new String(spare.chars, (spare.offset + (i+1)), spare.length - ((i + 1) - spare.offset))));
|
lon.add(Double.parseDouble(new String(spare.chars, (spare.offset + (i + 1)), spare.length - ((i + 1) - spare.offset))));
|
||||||
parsed = true;
|
parsed = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert parsed;
|
assert parsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ordinals build = builder.build(fieldDataType.getSettings());
|
Ordinals build = builder.build(fieldDataType.getSettings());
|
||||||
if (!build.isMultiValued()) {
|
if (!build.isMultiValued()) {
|
||||||
Docs ordinals = build.ordinals();
|
Docs ordinals = build.ordinals();
|
||||||
@ -137,7 +134,7 @@ public class GeoPointDoubleArrayIndexFieldData extends AbstractIndexFieldData<Ge
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public XFieldComparatorSource comparatorSource(@Nullable Object missingValue) {
|
public XFieldComparatorSource comparatorSource(@Nullable Object missingValue, SortMode sortMode) {
|
||||||
throw new ElasticSearchIllegalArgumentException("can't sort on geo_point field without using specific sorting feature, like geo_distance");
|
throw new ElasticSearchIllegalArgumentException("can't sort on geo_point field without using specific sorting feature, like geo_distance");
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -20,9 +20,9 @@
|
|||||||
package org.elasticsearch.index.fielddata.plain;
|
package org.elasticsearch.index.fielddata.plain;
|
||||||
|
|
||||||
import gnu.trove.list.array.TIntArrayList;
|
import gnu.trove.list.array.TIntArrayList;
|
||||||
import org.apache.lucene.index.*;
|
import org.apache.lucene.index.AtomicReader;
|
||||||
import org.apache.lucene.search.FieldCache;
|
import org.apache.lucene.index.AtomicReaderContext;
|
||||||
import org.apache.lucene.search.FieldCache.StopFillCacheException;
|
import org.apache.lucene.index.Terms;
|
||||||
import org.apache.lucene.util.BytesRef;
|
import org.apache.lucene.util.BytesRef;
|
||||||
import org.apache.lucene.util.BytesRefIterator;
|
import org.apache.lucene.util.BytesRefIterator;
|
||||||
import org.apache.lucene.util.FixedBitSet;
|
import org.apache.lucene.util.FixedBitSet;
|
||||||
@ -33,9 +33,10 @@ import org.elasticsearch.common.settings.Settings;
|
|||||||
import org.elasticsearch.index.Index;
|
import org.elasticsearch.index.Index;
|
||||||
import org.elasticsearch.index.fielddata.*;
|
import org.elasticsearch.index.fielddata.*;
|
||||||
import org.elasticsearch.index.fielddata.fieldcomparator.IntValuesComparatorSource;
|
import org.elasticsearch.index.fielddata.fieldcomparator.IntValuesComparatorSource;
|
||||||
|
import org.elasticsearch.index.fielddata.fieldcomparator.SortMode;
|
||||||
import org.elasticsearch.index.fielddata.ordinals.Ordinals;
|
import org.elasticsearch.index.fielddata.ordinals.Ordinals;
|
||||||
import org.elasticsearch.index.fielddata.ordinals.OrdinalsBuilder;
|
|
||||||
import org.elasticsearch.index.fielddata.ordinals.Ordinals.Docs;
|
import org.elasticsearch.index.fielddata.ordinals.Ordinals.Docs;
|
||||||
|
import org.elasticsearch.index.fielddata.ordinals.OrdinalsBuilder;
|
||||||
import org.elasticsearch.index.mapper.FieldMapper;
|
import org.elasticsearch.index.mapper.FieldMapper;
|
||||||
import org.elasticsearch.index.settings.IndexSettings;
|
import org.elasticsearch.index.settings.IndexSettings;
|
||||||
|
|
||||||
@ -95,7 +96,7 @@ public class IntArrayIndexFieldData extends AbstractIndexFieldData<IntArrayAtomi
|
|||||||
try {
|
try {
|
||||||
BytesRefIterator iter = builder.buildFromTerms(builder.wrapNumeric32Bit(terms.iterator(null)), reader.getLiveDocs());
|
BytesRefIterator iter = builder.buildFromTerms(builder.wrapNumeric32Bit(terms.iterator(null)), reader.getLiveDocs());
|
||||||
BytesRef term;
|
BytesRef term;
|
||||||
while((term = iter.next()) != null) {
|
while ((term = iter.next()) != null) {
|
||||||
values.add(NumericUtils.prefixCodedToInt(term));
|
values.add(NumericUtils.prefixCodedToInt(term));
|
||||||
}
|
}
|
||||||
Ordinals build = builder.build(fieldDataType.getSettings());
|
Ordinals build = builder.build(fieldDataType.getSettings());
|
||||||
@ -104,7 +105,7 @@ public class IntArrayIndexFieldData extends AbstractIndexFieldData<IntArrayAtomi
|
|||||||
int[] sValues = new int[reader.maxDoc()];
|
int[] sValues = new int[reader.maxDoc()];
|
||||||
int maxDoc = reader.maxDoc();
|
int maxDoc = reader.maxDoc();
|
||||||
for (int i = 0; i < maxDoc; i++) {
|
for (int i = 0; i < maxDoc; i++) {
|
||||||
sValues[i] = values.get(ordinals.getOrd(i));
|
sValues[i] = values.get(ordinals.getOrd(i));
|
||||||
}
|
}
|
||||||
final FixedBitSet set = builder.buildDocsWithValuesSet();
|
final FixedBitSet set = builder.buildDocsWithValuesSet();
|
||||||
if (set == null) {
|
if (set == null) {
|
||||||
@ -124,7 +125,7 @@ public class IntArrayIndexFieldData extends AbstractIndexFieldData<IntArrayAtomi
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public XFieldComparatorSource comparatorSource(@Nullable Object missingValue) {
|
public XFieldComparatorSource comparatorSource(@Nullable Object missingValue, SortMode sortMode) {
|
||||||
return new IntValuesComparatorSource(this, missingValue);
|
return new IntValuesComparatorSource(this, missingValue, sortMode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,9 +20,9 @@
|
|||||||
package org.elasticsearch.index.fielddata.plain;
|
package org.elasticsearch.index.fielddata.plain;
|
||||||
|
|
||||||
import gnu.trove.list.array.TLongArrayList;
|
import gnu.trove.list.array.TLongArrayList;
|
||||||
import org.apache.lucene.index.*;
|
import org.apache.lucene.index.AtomicReader;
|
||||||
import org.apache.lucene.search.FieldCache;
|
import org.apache.lucene.index.AtomicReaderContext;
|
||||||
import org.apache.lucene.search.FieldCache.StopFillCacheException;
|
import org.apache.lucene.index.Terms;
|
||||||
import org.apache.lucene.util.BytesRef;
|
import org.apache.lucene.util.BytesRef;
|
||||||
import org.apache.lucene.util.BytesRefIterator;
|
import org.apache.lucene.util.BytesRefIterator;
|
||||||
import org.apache.lucene.util.FixedBitSet;
|
import org.apache.lucene.util.FixedBitSet;
|
||||||
@ -33,9 +33,10 @@ import org.elasticsearch.common.settings.Settings;
|
|||||||
import org.elasticsearch.index.Index;
|
import org.elasticsearch.index.Index;
|
||||||
import org.elasticsearch.index.fielddata.*;
|
import org.elasticsearch.index.fielddata.*;
|
||||||
import org.elasticsearch.index.fielddata.fieldcomparator.LongValuesComparatorSource;
|
import org.elasticsearch.index.fielddata.fieldcomparator.LongValuesComparatorSource;
|
||||||
|
import org.elasticsearch.index.fielddata.fieldcomparator.SortMode;
|
||||||
import org.elasticsearch.index.fielddata.ordinals.Ordinals;
|
import org.elasticsearch.index.fielddata.ordinals.Ordinals;
|
||||||
import org.elasticsearch.index.fielddata.ordinals.OrdinalsBuilder;
|
|
||||||
import org.elasticsearch.index.fielddata.ordinals.Ordinals.Docs;
|
import org.elasticsearch.index.fielddata.ordinals.Ordinals.Docs;
|
||||||
|
import org.elasticsearch.index.fielddata.ordinals.OrdinalsBuilder;
|
||||||
import org.elasticsearch.index.mapper.FieldMapper;
|
import org.elasticsearch.index.mapper.FieldMapper;
|
||||||
import org.elasticsearch.index.settings.IndexSettings;
|
import org.elasticsearch.index.settings.IndexSettings;
|
||||||
|
|
||||||
@ -93,8 +94,9 @@ public class LongArrayIndexFieldData extends AbstractIndexFieldData<LongArrayAto
|
|||||||
values.add(0); // first "t" indicates null value
|
values.add(0); // first "t" indicates null value
|
||||||
OrdinalsBuilder builder = new OrdinalsBuilder(terms, reader.maxDoc());
|
OrdinalsBuilder builder = new OrdinalsBuilder(terms, reader.maxDoc());
|
||||||
try {
|
try {
|
||||||
BytesRefIterator iter = builder.buildFromTerms(builder.wrapNumeric64Bit(terms.iterator(null)), reader.getLiveDocs()); BytesRef term;
|
BytesRefIterator iter = builder.buildFromTerms(builder.wrapNumeric64Bit(terms.iterator(null)), reader.getLiveDocs());
|
||||||
while((term = iter.next()) != null) {
|
BytesRef term;
|
||||||
|
while ((term = iter.next()) != null) {
|
||||||
values.add(NumericUtils.prefixCodedToLong(term));
|
values.add(NumericUtils.prefixCodedToLong(term));
|
||||||
}
|
}
|
||||||
Ordinals build = builder.build(fieldDataType.getSettings());
|
Ordinals build = builder.build(fieldDataType.getSettings());
|
||||||
@ -103,7 +105,7 @@ public class LongArrayIndexFieldData extends AbstractIndexFieldData<LongArrayAto
|
|||||||
long[] sValues = new long[reader.maxDoc()];
|
long[] sValues = new long[reader.maxDoc()];
|
||||||
int maxDoc = reader.maxDoc();
|
int maxDoc = reader.maxDoc();
|
||||||
for (int i = 0; i < maxDoc; i++) {
|
for (int i = 0; i < maxDoc; i++) {
|
||||||
sValues[i] = values.get(ordinals.getOrd(i));
|
sValues[i] = values.get(ordinals.getOrd(i));
|
||||||
}
|
}
|
||||||
final FixedBitSet set = builder.buildDocsWithValuesSet();
|
final FixedBitSet set = builder.buildDocsWithValuesSet();
|
||||||
if (set == null) {
|
if (set == null) {
|
||||||
@ -124,7 +126,7 @@ public class LongArrayIndexFieldData extends AbstractIndexFieldData<LongArrayAto
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public XFieldComparatorSource comparatorSource(@Nullable Object missingValue) {
|
public XFieldComparatorSource comparatorSource(@Nullable Object missingValue, SortMode sortMode) {
|
||||||
return new LongValuesComparatorSource(this, missingValue);
|
return new LongValuesComparatorSource(this, missingValue, sortMode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,7 @@ import org.elasticsearch.index.fielddata.FieldDataType;
|
|||||||
import org.elasticsearch.index.fielddata.IndexFieldData;
|
import org.elasticsearch.index.fielddata.IndexFieldData;
|
||||||
import org.elasticsearch.index.fielddata.IndexFieldDataCache;
|
import org.elasticsearch.index.fielddata.IndexFieldDataCache;
|
||||||
import org.elasticsearch.index.fielddata.fieldcomparator.BytesRefFieldComparatorSource;
|
import org.elasticsearch.index.fielddata.fieldcomparator.BytesRefFieldComparatorSource;
|
||||||
|
import org.elasticsearch.index.fielddata.fieldcomparator.SortMode;
|
||||||
import org.elasticsearch.index.fielddata.ordinals.Ordinals;
|
import org.elasticsearch.index.fielddata.ordinals.Ordinals;
|
||||||
import org.elasticsearch.index.fielddata.ordinals.OrdinalsBuilder;
|
import org.elasticsearch.index.fielddata.ordinals.OrdinalsBuilder;
|
||||||
import org.elasticsearch.index.mapper.FieldMapper;
|
import org.elasticsearch.index.mapper.FieldMapper;
|
||||||
@ -144,7 +145,7 @@ public class PagedBytesIndexFieldData extends AbstractIndexFieldData<PagedBytesA
|
|||||||
PagedBytes.Reader bytesReader = bytes.freeze(true);
|
PagedBytes.Reader bytesReader = bytes.freeze(true);
|
||||||
PackedInts.Reader termOrdToBytesOffsetReader = termOrdToBytesOffset.getMutable();
|
PackedInts.Reader termOrdToBytesOffsetReader = termOrdToBytesOffset.getMutable();
|
||||||
final Ordinals ordinals = builder.build(fieldDataType.getSettings());
|
final Ordinals ordinals = builder.build(fieldDataType.getSettings());
|
||||||
|
|
||||||
return new PagedBytesAtomicFieldData(bytesReader, termOrdToBytesOffsetReader, ordinals);
|
return new PagedBytesAtomicFieldData(bytesReader, termOrdToBytesOffsetReader, ordinals);
|
||||||
} finally {
|
} finally {
|
||||||
builder.close();
|
builder.close();
|
||||||
@ -152,8 +153,8 @@ public class PagedBytesIndexFieldData extends AbstractIndexFieldData<PagedBytesA
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public XFieldComparatorSource comparatorSource(@Nullable Object missingValue) {
|
public XFieldComparatorSource comparatorSource(@Nullable Object missingValue, SortMode sortMode) {
|
||||||
// TODO support "missingValue" for sortMissingValue options here...
|
// TODO support "missingValue" for sortMissingValue options here...
|
||||||
return new BytesRefFieldComparatorSource(this);
|
return new BytesRefFieldComparatorSource(this, sortMode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,9 +20,9 @@
|
|||||||
package org.elasticsearch.index.fielddata.plain;
|
package org.elasticsearch.index.fielddata.plain;
|
||||||
|
|
||||||
import gnu.trove.list.array.TShortArrayList;
|
import gnu.trove.list.array.TShortArrayList;
|
||||||
import org.apache.lucene.index.*;
|
import org.apache.lucene.index.AtomicReader;
|
||||||
import org.apache.lucene.search.FieldCache;
|
import org.apache.lucene.index.AtomicReaderContext;
|
||||||
import org.apache.lucene.search.FieldCache.StopFillCacheException;
|
import org.apache.lucene.index.Terms;
|
||||||
import org.apache.lucene.util.BytesRef;
|
import org.apache.lucene.util.BytesRef;
|
||||||
import org.apache.lucene.util.BytesRefIterator;
|
import org.apache.lucene.util.BytesRefIterator;
|
||||||
import org.apache.lucene.util.FixedBitSet;
|
import org.apache.lucene.util.FixedBitSet;
|
||||||
@ -33,9 +33,10 @@ import org.elasticsearch.common.settings.Settings;
|
|||||||
import org.elasticsearch.index.Index;
|
import org.elasticsearch.index.Index;
|
||||||
import org.elasticsearch.index.fielddata.*;
|
import org.elasticsearch.index.fielddata.*;
|
||||||
import org.elasticsearch.index.fielddata.fieldcomparator.ShortValuesComparatorSource;
|
import org.elasticsearch.index.fielddata.fieldcomparator.ShortValuesComparatorSource;
|
||||||
|
import org.elasticsearch.index.fielddata.fieldcomparator.SortMode;
|
||||||
import org.elasticsearch.index.fielddata.ordinals.Ordinals;
|
import org.elasticsearch.index.fielddata.ordinals.Ordinals;
|
||||||
import org.elasticsearch.index.fielddata.ordinals.OrdinalsBuilder;
|
|
||||||
import org.elasticsearch.index.fielddata.ordinals.Ordinals.Docs;
|
import org.elasticsearch.index.fielddata.ordinals.Ordinals.Docs;
|
||||||
|
import org.elasticsearch.index.fielddata.ordinals.OrdinalsBuilder;
|
||||||
import org.elasticsearch.index.mapper.FieldMapper;
|
import org.elasticsearch.index.mapper.FieldMapper;
|
||||||
import org.elasticsearch.index.settings.IndexSettings;
|
import org.elasticsearch.index.settings.IndexSettings;
|
||||||
|
|
||||||
@ -95,17 +96,17 @@ public class ShortArrayIndexFieldData extends AbstractIndexFieldData<ShortArrayA
|
|||||||
try {
|
try {
|
||||||
BytesRefIterator iter = builder.buildFromTerms(builder.wrapNumeric32Bit(terms.iterator(null)), reader.getLiveDocs());
|
BytesRefIterator iter = builder.buildFromTerms(builder.wrapNumeric32Bit(terms.iterator(null)), reader.getLiveDocs());
|
||||||
BytesRef term;
|
BytesRef term;
|
||||||
while((term = iter.next()) != null) {
|
while ((term = iter.next()) != null) {
|
||||||
values.add((short) NumericUtils.prefixCodedToInt(term));
|
values.add((short) NumericUtils.prefixCodedToInt(term));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ordinals build = builder.build(fieldDataType.getSettings());
|
Ordinals build = builder.build(fieldDataType.getSettings());
|
||||||
if (!build.isMultiValued()) {
|
if (!build.isMultiValued()) {
|
||||||
Docs ordinals = build.ordinals();
|
Docs ordinals = build.ordinals();
|
||||||
short[] sValues = new short[reader.maxDoc()];
|
short[] sValues = new short[reader.maxDoc()];
|
||||||
int maxDoc = reader.maxDoc();
|
int maxDoc = reader.maxDoc();
|
||||||
for (int i = 0; i < maxDoc; i++) {
|
for (int i = 0; i < maxDoc; i++) {
|
||||||
sValues[i] = values.get(ordinals.getOrd(i));
|
sValues[i] = values.get(ordinals.getOrd(i));
|
||||||
}
|
}
|
||||||
final FixedBitSet set = builder.buildDocsWithValuesSet();
|
final FixedBitSet set = builder.buildDocsWithValuesSet();
|
||||||
if (set == null) {
|
if (set == null) {
|
||||||
@ -125,7 +126,7 @@ public class ShortArrayIndexFieldData extends AbstractIndexFieldData<ShortArrayA
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public XFieldComparatorSource comparatorSource(@Nullable Object missingValue) {
|
public XFieldComparatorSource comparatorSource(@Nullable Object missingValue, SortMode sortMode) {
|
||||||
return new ShortValuesComparatorSource(this, missingValue);
|
return new ShortValuesComparatorSource(this, missingValue, sortMode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,8 @@ public class FieldSortBuilder extends SortBuilder {
|
|||||||
|
|
||||||
private Boolean ignoreUnampped;
|
private Boolean ignoreUnampped;
|
||||||
|
|
||||||
|
private String sortMode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new sort based on a document field.
|
* Constructs a new sort based on a document field.
|
||||||
*
|
*
|
||||||
@ -73,6 +75,17 @@ public class FieldSortBuilder extends SortBuilder {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines what values to pick in the case a document contains multiple values for the targeted sort field.
|
||||||
|
* Possible values: min, max, sum and avg
|
||||||
|
* <p/>
|
||||||
|
* The last two values are only applicable for number based fields.
|
||||||
|
*/
|
||||||
|
public FieldSortBuilder sortMode(String sortMode) {
|
||||||
|
this.sortMode = sortMode;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||||
builder.startObject(fieldName);
|
builder.startObject(fieldName);
|
||||||
@ -85,6 +98,9 @@ public class FieldSortBuilder extends SortBuilder {
|
|||||||
if (ignoreUnampped != null) {
|
if (ignoreUnampped != null) {
|
||||||
builder.field("ignore_unmapped", ignoreUnampped);
|
builder.field("ignore_unmapped", ignoreUnampped);
|
||||||
}
|
}
|
||||||
|
if (sortMode != null) {
|
||||||
|
builder.field("sort_mode", sortMode);
|
||||||
|
}
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,9 @@ import org.apache.lucene.search.Sort;
|
|||||||
import org.apache.lucene.search.SortField;
|
import org.apache.lucene.search.SortField;
|
||||||
import org.elasticsearch.common.Nullable;
|
import org.elasticsearch.common.Nullable;
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
|
import org.elasticsearch.index.fielddata.fieldcomparator.SortMode;
|
||||||
import org.elasticsearch.index.mapper.FieldMapper;
|
import org.elasticsearch.index.mapper.FieldMapper;
|
||||||
|
import org.elasticsearch.index.mapper.core.NumberFieldMapper;
|
||||||
import org.elasticsearch.search.SearchParseElement;
|
import org.elasticsearch.search.SearchParseElement;
|
||||||
import org.elasticsearch.search.SearchParseException;
|
import org.elasticsearch.search.SearchParseException;
|
||||||
import org.elasticsearch.search.internal.SearchContext;
|
import org.elasticsearch.search.internal.SearchContext;
|
||||||
@ -69,7 +71,7 @@ public class SortParseElement implements SearchParseElement {
|
|||||||
if (token == XContentParser.Token.START_OBJECT) {
|
if (token == XContentParser.Token.START_OBJECT) {
|
||||||
addCompoundSortField(parser, context, sortFields);
|
addCompoundSortField(parser, context, sortFields);
|
||||||
} else if (token == XContentParser.Token.VALUE_STRING) {
|
} else if (token == XContentParser.Token.VALUE_STRING) {
|
||||||
addSortField(context, sortFields, parser.text(), false, false, null);
|
addSortField(context, sortFields, parser.text(), false, false, null, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -103,6 +105,7 @@ public class SortParseElement implements SearchParseElement {
|
|||||||
String missing = null;
|
String missing = null;
|
||||||
String innerJsonName = null;
|
String innerJsonName = null;
|
||||||
boolean ignoreUnmapped = false;
|
boolean ignoreUnmapped = false;
|
||||||
|
SortMode sortMode = null;
|
||||||
token = parser.nextToken();
|
token = parser.nextToken();
|
||||||
if (token == XContentParser.Token.VALUE_STRING) {
|
if (token == XContentParser.Token.VALUE_STRING) {
|
||||||
String direction = parser.text();
|
String direction = parser.text();
|
||||||
@ -111,7 +114,7 @@ public class SortParseElement implements SearchParseElement {
|
|||||||
} else if (direction.equals("desc")) {
|
} else if (direction.equals("desc")) {
|
||||||
reverse = !SCORE_FIELD_NAME.equals(fieldName);
|
reverse = !SCORE_FIELD_NAME.equals(fieldName);
|
||||||
}
|
}
|
||||||
addSortField(context, sortFields, fieldName, reverse, ignoreUnmapped, missing);
|
addSortField(context, sortFields, fieldName, reverse, ignoreUnmapped, missing, sortMode);
|
||||||
} else {
|
} else {
|
||||||
if (parsers.containsKey(fieldName)) {
|
if (parsers.containsKey(fieldName)) {
|
||||||
sortFields.add(parsers.get(fieldName).parse(parser, context));
|
sortFields.add(parsers.get(fieldName).parse(parser, context));
|
||||||
@ -132,17 +135,19 @@ public class SortParseElement implements SearchParseElement {
|
|||||||
missing = parser.textOrNull();
|
missing = parser.textOrNull();
|
||||||
} else if ("ignore_unmapped".equals(innerJsonName) || "ignoreUnmapped".equals(innerJsonName)) {
|
} else if ("ignore_unmapped".equals(innerJsonName) || "ignoreUnmapped".equals(innerJsonName)) {
|
||||||
ignoreUnmapped = parser.booleanValue();
|
ignoreUnmapped = parser.booleanValue();
|
||||||
|
} else if ("sort_mode".equals(innerJsonName) || "sortMode".equals(innerJsonName)) {
|
||||||
|
sortMode = SortMode.fromString(parser.text());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
addSortField(context, sortFields, fieldName, reverse, ignoreUnmapped, missing);
|
addSortField(context, sortFields, fieldName, reverse, ignoreUnmapped, missing, sortMode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addSortField(SearchContext context, List<SortField> sortFields, String fieldName, boolean reverse, boolean ignoreUnmapped, @Nullable final String missing) {
|
private void addSortField(SearchContext context, List<SortField> sortFields, String fieldName, boolean reverse, boolean ignoreUnmapped, @Nullable final String missing, SortMode sortMode) {
|
||||||
if (SCORE_FIELD_NAME.equals(fieldName)) {
|
if (SCORE_FIELD_NAME.equals(fieldName)) {
|
||||||
if (reverse) {
|
if (reverse) {
|
||||||
sortFields.add(SORT_SCORE_REVERSE);
|
sortFields.add(SORT_SCORE_REVERSE);
|
||||||
@ -173,7 +178,14 @@ public class SortParseElement implements SearchParseElement {
|
|||||||
}
|
}
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
sortFields.add(new SortField(fieldMapper.names().indexName(), context.fieldData().getForField(fieldMapper).comparatorSource(missing), reverse));
|
// We only support AVG and SUM on number based fields
|
||||||
|
if (!(fieldMapper instanceof NumberFieldMapper) && (sortMode == SortMode.SUM || sortMode == SortMode.AVG)) {
|
||||||
|
sortMode = null;
|
||||||
|
}
|
||||||
|
if (sortMode == null) {
|
||||||
|
sortMode = reverse ? SortMode.MAX : SortMode.MIN;
|
||||||
|
}
|
||||||
|
sortFields.add(new SortField(fieldMapper.names().indexName(), context.fieldData().getForField(fieldMapper).comparatorSource(missing, sortMode), reverse));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -693,6 +693,24 @@ public class SimpleSortTests extends AbstractNodesTests {
|
|||||||
assertThat(searchResponse.hits().getAt(2).id(), equalTo(Integer.toString(3)));
|
assertThat(searchResponse.hits().getAt(2).id(), equalTo(Integer.toString(3)));
|
||||||
assertThat(((Number) searchResponse.hits().getAt(2).sortValues()[0]).longValue(), equalTo(3l));
|
assertThat(((Number) searchResponse.hits().getAt(2).sortValues()[0]).longValue(), equalTo(3l));
|
||||||
|
|
||||||
|
searchResponse = client.prepareSearch()
|
||||||
|
.setQuery(matchAllQuery())
|
||||||
|
.setSize(10)
|
||||||
|
.addSort(SortBuilders.fieldSort("long_values").order(SortOrder.DESC).sortMode("sum"))
|
||||||
|
.execute().actionGet();
|
||||||
|
|
||||||
|
assertThat(searchResponse.hits().getTotalHits(), equalTo(3l));
|
||||||
|
assertThat(searchResponse.hits().hits().length, equalTo(3));
|
||||||
|
|
||||||
|
assertThat(searchResponse.hits().getAt(0).id(), equalTo(Integer.toString(2)));
|
||||||
|
assertThat(((Number) searchResponse.hits().getAt(0).sortValues()[0]).longValue(), equalTo(53l));
|
||||||
|
|
||||||
|
assertThat(searchResponse.hits().getAt(1).id(), equalTo(Integer.toString(1)));
|
||||||
|
assertThat(((Number) searchResponse.hits().getAt(1).sortValues()[0]).longValue(), equalTo(24l));
|
||||||
|
|
||||||
|
assertThat(searchResponse.hits().getAt(2).id(), equalTo(Integer.toString(3)));
|
||||||
|
assertThat(((Number) searchResponse.hits().getAt(2).sortValues()[0]).longValue(), equalTo(2l));
|
||||||
|
|
||||||
searchResponse = client.prepareSearch()
|
searchResponse = client.prepareSearch()
|
||||||
.setQuery(matchAllQuery())
|
.setQuery(matchAllQuery())
|
||||||
.setSize(10)
|
.setSize(10)
|
||||||
|
@ -25,7 +25,9 @@ import org.apache.lucene.document.StringField;
|
|||||||
import org.apache.lucene.index.DirectoryReader;
|
import org.apache.lucene.index.DirectoryReader;
|
||||||
import org.apache.lucene.search.*;
|
import org.apache.lucene.search.*;
|
||||||
import org.elasticsearch.index.fielddata.*;
|
import org.elasticsearch.index.fielddata.*;
|
||||||
import org.elasticsearch.index.fielddata.util.*;
|
import org.elasticsearch.index.fielddata.fieldcomparator.SortMode;
|
||||||
|
import org.elasticsearch.index.fielddata.util.DoubleArrayRef;
|
||||||
|
import org.elasticsearch.index.fielddata.util.LongArrayRef;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
@ -144,14 +146,14 @@ public abstract class NumericFieldDataTests extends StringFieldDataTests {
|
|||||||
TopFieldDocs topDocs;
|
TopFieldDocs topDocs;
|
||||||
|
|
||||||
topDocs = searcher.search(new MatchAllDocsQuery(), 10,
|
topDocs = searcher.search(new MatchAllDocsQuery(), 10,
|
||||||
new Sort(new SortField("value", indexFieldData.comparatorSource(null))));
|
new Sort(new SortField("value", indexFieldData.comparatorSource(null, SortMode.MIN))));
|
||||||
assertThat(topDocs.totalHits, equalTo(3));
|
assertThat(topDocs.totalHits, equalTo(3));
|
||||||
assertThat(topDocs.scoreDocs[0].doc, equalTo(1));
|
assertThat(topDocs.scoreDocs[0].doc, equalTo(1));
|
||||||
assertThat(topDocs.scoreDocs[1].doc, equalTo(0));
|
assertThat(topDocs.scoreDocs[1].doc, equalTo(0));
|
||||||
assertThat(topDocs.scoreDocs[2].doc, equalTo(2));
|
assertThat(topDocs.scoreDocs[2].doc, equalTo(2));
|
||||||
|
|
||||||
topDocs = searcher.search(new MatchAllDocsQuery(), 10,
|
topDocs = searcher.search(new MatchAllDocsQuery(), 10,
|
||||||
new Sort(new SortField("value", indexFieldData.comparatorSource(null), true)));
|
new Sort(new SortField("value", indexFieldData.comparatorSource(null, SortMode.MAX), true)));
|
||||||
assertThat(topDocs.totalHits, equalTo(3));
|
assertThat(topDocs.totalHits, equalTo(3));
|
||||||
assertThat(topDocs.scoreDocs[0].doc, equalTo(2));
|
assertThat(topDocs.scoreDocs[0].doc, equalTo(2));
|
||||||
assertThat(topDocs.scoreDocs[1].doc, equalTo(0));
|
assertThat(topDocs.scoreDocs[1].doc, equalTo(0));
|
||||||
@ -256,42 +258,42 @@ public abstract class NumericFieldDataTests extends StringFieldDataTests {
|
|||||||
TopFieldDocs topDocs;
|
TopFieldDocs topDocs;
|
||||||
|
|
||||||
topDocs = searcher.search(new MatchAllDocsQuery(), 10,
|
topDocs = searcher.search(new MatchAllDocsQuery(), 10,
|
||||||
new Sort(new SortField("value", indexFieldData.comparatorSource(null)))); // defaults to _last
|
new Sort(new SortField("value", indexFieldData.comparatorSource(null, SortMode.MIN)))); // defaults to _last
|
||||||
assertThat(topDocs.totalHits, equalTo(3));
|
assertThat(topDocs.totalHits, equalTo(3));
|
||||||
assertThat(topDocs.scoreDocs[0].doc, equalTo(0));
|
assertThat(topDocs.scoreDocs[0].doc, equalTo(0));
|
||||||
assertThat(topDocs.scoreDocs[1].doc, equalTo(2));
|
assertThat(topDocs.scoreDocs[1].doc, equalTo(2));
|
||||||
assertThat(topDocs.scoreDocs[2].doc, equalTo(1));
|
assertThat(topDocs.scoreDocs[2].doc, equalTo(1));
|
||||||
|
|
||||||
topDocs = searcher.search(new MatchAllDocsQuery(), 10,
|
topDocs = searcher.search(new MatchAllDocsQuery(), 10,
|
||||||
new Sort(new SortField("value", indexFieldData.comparatorSource(null), true))); // defaults to _last
|
new Sort(new SortField("value", indexFieldData.comparatorSource(null, SortMode.MAX), true))); // defaults to _last
|
||||||
assertThat(topDocs.totalHits, equalTo(3));
|
assertThat(topDocs.totalHits, equalTo(3));
|
||||||
assertThat(topDocs.scoreDocs[0].doc, equalTo(2));
|
assertThat(topDocs.scoreDocs[0].doc, equalTo(2));
|
||||||
assertThat(topDocs.scoreDocs[1].doc, equalTo(0));
|
assertThat(topDocs.scoreDocs[1].doc, equalTo(0));
|
||||||
assertThat(topDocs.scoreDocs[2].doc, equalTo(1));
|
assertThat(topDocs.scoreDocs[2].doc, equalTo(1));
|
||||||
|
|
||||||
topDocs = searcher.search(new MatchAllDocsQuery(), 10,
|
topDocs = searcher.search(new MatchAllDocsQuery(), 10,
|
||||||
new Sort(new SortField("value", indexFieldData.comparatorSource("_first"))));
|
new Sort(new SortField("value", indexFieldData.comparatorSource("_first", SortMode.MIN))));
|
||||||
assertThat(topDocs.totalHits, equalTo(3));
|
assertThat(topDocs.totalHits, equalTo(3));
|
||||||
assertThat(topDocs.scoreDocs[0].doc, equalTo(1));
|
assertThat(topDocs.scoreDocs[0].doc, equalTo(1));
|
||||||
assertThat(topDocs.scoreDocs[1].doc, equalTo(0));
|
assertThat(topDocs.scoreDocs[1].doc, equalTo(0));
|
||||||
assertThat(topDocs.scoreDocs[2].doc, equalTo(2));
|
assertThat(topDocs.scoreDocs[2].doc, equalTo(2));
|
||||||
|
|
||||||
topDocs = searcher.search(new MatchAllDocsQuery(), 10,
|
topDocs = searcher.search(new MatchAllDocsQuery(), 10,
|
||||||
new Sort(new SortField("value", indexFieldData.comparatorSource("_first"), true)));
|
new Sort(new SortField("value", indexFieldData.comparatorSource("_first", SortMode.MAX), true)));
|
||||||
assertThat(topDocs.totalHits, equalTo(3));
|
assertThat(topDocs.totalHits, equalTo(3));
|
||||||
assertThat(topDocs.scoreDocs[0].doc, equalTo(1));
|
assertThat(topDocs.scoreDocs[0].doc, equalTo(1));
|
||||||
assertThat(topDocs.scoreDocs[1].doc, equalTo(2));
|
assertThat(topDocs.scoreDocs[1].doc, equalTo(2));
|
||||||
assertThat(topDocs.scoreDocs[2].doc, equalTo(0));
|
assertThat(topDocs.scoreDocs[2].doc, equalTo(0));
|
||||||
|
|
||||||
topDocs = searcher.search(new MatchAllDocsQuery(), 10,
|
topDocs = searcher.search(new MatchAllDocsQuery(), 10,
|
||||||
new Sort(new SortField("value", indexFieldData.comparatorSource("1"))));
|
new Sort(new SortField("value", indexFieldData.comparatorSource("1", SortMode.MIN))));
|
||||||
assertThat(topDocs.totalHits, equalTo(3));
|
assertThat(topDocs.totalHits, equalTo(3));
|
||||||
assertThat(topDocs.scoreDocs[0].doc, equalTo(1));
|
assertThat(topDocs.scoreDocs[0].doc, equalTo(1));
|
||||||
assertThat(topDocs.scoreDocs[1].doc, equalTo(0));
|
assertThat(topDocs.scoreDocs[1].doc, equalTo(0));
|
||||||
assertThat(topDocs.scoreDocs[2].doc, equalTo(2));
|
assertThat(topDocs.scoreDocs[2].doc, equalTo(2));
|
||||||
|
|
||||||
topDocs = searcher.search(new MatchAllDocsQuery(), 10,
|
topDocs = searcher.search(new MatchAllDocsQuery(), 10,
|
||||||
new Sort(new SortField("value", indexFieldData.comparatorSource("1"), true)));
|
new Sort(new SortField("value", indexFieldData.comparatorSource("1", SortMode.MAX), true)));
|
||||||
assertThat(topDocs.totalHits, equalTo(3));
|
assertThat(topDocs.totalHits, equalTo(3));
|
||||||
assertThat(topDocs.scoreDocs[0].doc, equalTo(2));
|
assertThat(topDocs.scoreDocs[0].doc, equalTo(2));
|
||||||
assertThat(topDocs.scoreDocs[1].doc, equalTo(0));
|
assertThat(topDocs.scoreDocs[1].doc, equalTo(0));
|
||||||
@ -610,7 +612,7 @@ public abstract class NumericFieldDataTests extends StringFieldDataTests {
|
|||||||
|
|
||||||
IndexSearcher searcher = new IndexSearcher(DirectoryReader.open(writer, true));
|
IndexSearcher searcher = new IndexSearcher(DirectoryReader.open(writer, true));
|
||||||
TopFieldDocs topDocs = searcher.search(new MatchAllDocsQuery(), 10,
|
TopFieldDocs topDocs = searcher.search(new MatchAllDocsQuery(), 10,
|
||||||
new Sort(new SortField("value", indexFieldData.comparatorSource(null)))); // defaults to _last
|
new Sort(new SortField("value", indexFieldData.comparatorSource(null, SortMode.MIN)))); // defaults to _last
|
||||||
assertThat(topDocs.totalHits, equalTo(8));
|
assertThat(topDocs.totalHits, equalTo(8));
|
||||||
assertThat(topDocs.scoreDocs.length, equalTo(8));
|
assertThat(topDocs.scoreDocs.length, equalTo(8));
|
||||||
assertThat(topDocs.scoreDocs[0].doc, equalTo(7));
|
assertThat(topDocs.scoreDocs[0].doc, equalTo(7));
|
||||||
@ -631,7 +633,7 @@ public abstract class NumericFieldDataTests extends StringFieldDataTests {
|
|||||||
// assertThat(((FieldDoc) topDocs.scoreDocs[7]).fields[0], equalTo(null));
|
// assertThat(((FieldDoc) topDocs.scoreDocs[7]).fields[0], equalTo(null));
|
||||||
|
|
||||||
topDocs = searcher.search(new MatchAllDocsQuery(), 10,
|
topDocs = searcher.search(new MatchAllDocsQuery(), 10,
|
||||||
new Sort(new SortField("value", indexFieldData.comparatorSource(null), true))); // defaults to _last
|
new Sort(new SortField("value", indexFieldData.comparatorSource(null, SortMode.MAX), true))); // defaults to _last
|
||||||
assertThat(topDocs.totalHits, equalTo(8));
|
assertThat(topDocs.totalHits, equalTo(8));
|
||||||
assertThat(topDocs.scoreDocs.length, equalTo(8));
|
assertThat(topDocs.scoreDocs.length, equalTo(8));
|
||||||
assertThat(topDocs.scoreDocs[0].doc, equalTo(6));
|
assertThat(topDocs.scoreDocs[0].doc, equalTo(6));
|
||||||
@ -651,8 +653,96 @@ public abstract class NumericFieldDataTests extends StringFieldDataTests {
|
|||||||
assertThat(topDocs.scoreDocs[7].doc, equalTo(5));
|
assertThat(topDocs.scoreDocs[7].doc, equalTo(5));
|
||||||
// assertThat(((FieldDoc) topDocs.scoreDocs[7]).fields[0], equalTo(null));
|
// assertThat(((FieldDoc) topDocs.scoreDocs[7]).fields[0], equalTo(null));
|
||||||
|
|
||||||
|
searcher = new IndexSearcher(DirectoryReader.open(writer, true));
|
||||||
topDocs = searcher.search(new MatchAllDocsQuery(), 10,
|
topDocs = searcher.search(new MatchAllDocsQuery(), 10,
|
||||||
new Sort(new SortField("value", indexFieldData.comparatorSource("_first"))));
|
new Sort(new SortField("value", indexFieldData.comparatorSource(null, SortMode.SUM)))); // defaults to _last
|
||||||
|
assertThat(topDocs.totalHits, equalTo(8));
|
||||||
|
assertThat(topDocs.scoreDocs.length, equalTo(8));
|
||||||
|
assertThat(topDocs.scoreDocs[0].doc, equalTo(7));
|
||||||
|
assertThat(((Number) ((FieldDoc) topDocs.scoreDocs[0]).fields[0]).intValue(), equalTo(-27));
|
||||||
|
assertThat(topDocs.scoreDocs[1].doc, equalTo(2));
|
||||||
|
assertThat(((Number) ((FieldDoc) topDocs.scoreDocs[1]).fields[0]).intValue(), equalTo(3));
|
||||||
|
assertThat(topDocs.scoreDocs[2].doc, equalTo(0));
|
||||||
|
assertThat(((Number) ((FieldDoc) topDocs.scoreDocs[2]).fields[0]).intValue(), equalTo(6));
|
||||||
|
assertThat(topDocs.scoreDocs[3].doc, equalTo(3));
|
||||||
|
assertThat(((Number) ((FieldDoc) topDocs.scoreDocs[3]).fields[0]).intValue(), equalTo(15));
|
||||||
|
assertThat(topDocs.scoreDocs[4].doc, equalTo(4));
|
||||||
|
assertThat(((Number) ((FieldDoc) topDocs.scoreDocs[4]).fields[0]).intValue(), equalTo(21));
|
||||||
|
assertThat(topDocs.scoreDocs[5].doc, equalTo(6));
|
||||||
|
assertThat(((Number) ((FieldDoc) topDocs.scoreDocs[5]).fields[0]).intValue(), equalTo(27));
|
||||||
|
assertThat(topDocs.scoreDocs[6].doc, equalTo(1));
|
||||||
|
// assertThat(((FieldDoc) topDocs.scoreDocs[6]).fields[0], equalTo(null));
|
||||||
|
assertThat(topDocs.scoreDocs[7].doc, equalTo(5));
|
||||||
|
// assertThat(((FieldDoc) topDocs.scoreDocs[7]).fields[0], equalTo(null));
|
||||||
|
|
||||||
|
searcher = new IndexSearcher(DirectoryReader.open(writer, true));
|
||||||
|
topDocs = searcher.search(new MatchAllDocsQuery(), 10,
|
||||||
|
new Sort(new SortField("value", indexFieldData.comparatorSource(null, SortMode.SUM), true))); // defaults to _last
|
||||||
|
assertThat(topDocs.totalHits, equalTo(8));
|
||||||
|
assertThat(topDocs.scoreDocs.length, equalTo(8));
|
||||||
|
assertThat(topDocs.scoreDocs[0].doc, equalTo(6));
|
||||||
|
assertThat(((Number) ((FieldDoc) topDocs.scoreDocs[0]).fields[0]).intValue(), equalTo(27));
|
||||||
|
assertThat(topDocs.scoreDocs[1].doc, equalTo(4));
|
||||||
|
assertThat(((Number) ((FieldDoc) topDocs.scoreDocs[1]).fields[0]).intValue(), equalTo(21));
|
||||||
|
assertThat(topDocs.scoreDocs[2].doc, equalTo(3));
|
||||||
|
assertThat(((Number) ((FieldDoc) topDocs.scoreDocs[2]).fields[0]).intValue(), equalTo(15));
|
||||||
|
assertThat(topDocs.scoreDocs[3].doc, equalTo(0));
|
||||||
|
assertThat(((Number) ((FieldDoc) topDocs.scoreDocs[3]).fields[0]).intValue(), equalTo(6));
|
||||||
|
assertThat(topDocs.scoreDocs[4].doc, equalTo(2));
|
||||||
|
assertThat(((Number) ((FieldDoc) topDocs.scoreDocs[4]).fields[0]).intValue(), equalTo(3));
|
||||||
|
assertThat(topDocs.scoreDocs[5].doc, equalTo(7));
|
||||||
|
assertThat(((Number) ((FieldDoc) topDocs.scoreDocs[5]).fields[0]).intValue(), equalTo(-27));
|
||||||
|
assertThat(topDocs.scoreDocs[6].doc, equalTo(1));
|
||||||
|
// assertThat(((FieldDoc) topDocs.scoreDocs[6]).fields[0], equalTo(null));
|
||||||
|
assertThat(topDocs.scoreDocs[7].doc, equalTo(5));
|
||||||
|
// assertThat(((FieldDoc) topDocs.scoreDocs[7]).fields[0], equalTo(null));
|
||||||
|
|
||||||
|
searcher = new IndexSearcher(DirectoryReader.open(writer, true));
|
||||||
|
topDocs = searcher.search(new MatchAllDocsQuery(), 10,
|
||||||
|
new Sort(new SortField("value", indexFieldData.comparatorSource(null, SortMode.AVG)))); // defaults to _last
|
||||||
|
assertThat(topDocs.totalHits, equalTo(8));
|
||||||
|
assertThat(topDocs.scoreDocs.length, equalTo(8));
|
||||||
|
assertThat(topDocs.scoreDocs[0].doc, equalTo(7));
|
||||||
|
assertThat(((Number) ((FieldDoc) topDocs.scoreDocs[0]).fields[0]).intValue(), equalTo(-9));
|
||||||
|
assertThat(topDocs.scoreDocs[1].doc, equalTo(0));
|
||||||
|
assertThat(((Number) ((FieldDoc) topDocs.scoreDocs[1]).fields[0]).intValue(), equalTo(3));
|
||||||
|
assertThat(topDocs.scoreDocs[2].doc, equalTo(2));
|
||||||
|
assertThat(((Number) ((FieldDoc) topDocs.scoreDocs[2]).fields[0]).intValue(), equalTo(3));
|
||||||
|
assertThat(topDocs.scoreDocs[3].doc, equalTo(3));
|
||||||
|
assertThat(((Number) ((FieldDoc) topDocs.scoreDocs[3]).fields[0]).intValue(), equalTo(5));
|
||||||
|
assertThat(topDocs.scoreDocs[4].doc, equalTo(4));
|
||||||
|
assertThat(((Number) ((FieldDoc) topDocs.scoreDocs[4]).fields[0]).intValue(), equalTo(7));
|
||||||
|
assertThat(topDocs.scoreDocs[5].doc, equalTo(6));
|
||||||
|
assertThat(((Number) ((FieldDoc) topDocs.scoreDocs[5]).fields[0]).intValue(), equalTo(9));
|
||||||
|
assertThat(topDocs.scoreDocs[6].doc, equalTo(1));
|
||||||
|
// assertThat(((FieldDoc) topDocs.scoreDocs[6]).fields[0], equalTo(null));
|
||||||
|
assertThat(topDocs.scoreDocs[7].doc, equalTo(5));
|
||||||
|
// assertThat(((FieldDoc) topDocs.scoreDocs[7]).fields[0], equalTo(null));
|
||||||
|
|
||||||
|
searcher = new IndexSearcher(DirectoryReader.open(writer, true));
|
||||||
|
topDocs = searcher.search(new MatchAllDocsQuery(), 10,
|
||||||
|
new Sort(new SortField("value", indexFieldData.comparatorSource(null, SortMode.AVG), true))); // defaults to _last
|
||||||
|
assertThat(topDocs.totalHits, equalTo(8));
|
||||||
|
assertThat(topDocs.scoreDocs.length, equalTo(8));
|
||||||
|
assertThat(topDocs.scoreDocs[0].doc, equalTo(6));
|
||||||
|
assertThat(((Number) ((FieldDoc) topDocs.scoreDocs[0]).fields[0]).intValue(), equalTo(9));
|
||||||
|
assertThat(topDocs.scoreDocs[1].doc, equalTo(4));
|
||||||
|
assertThat(((Number) ((FieldDoc) topDocs.scoreDocs[1]).fields[0]).intValue(), equalTo(7));
|
||||||
|
assertThat(topDocs.scoreDocs[2].doc, equalTo(3));
|
||||||
|
assertThat(((Number) ((FieldDoc) topDocs.scoreDocs[2]).fields[0]).intValue(), equalTo(5));
|
||||||
|
assertThat(topDocs.scoreDocs[3].doc, equalTo(0));
|
||||||
|
assertThat(((Number) ((FieldDoc) topDocs.scoreDocs[3]).fields[0]).intValue(), equalTo(3));
|
||||||
|
assertThat(topDocs.scoreDocs[4].doc, equalTo(2));
|
||||||
|
assertThat(((Number) ((FieldDoc) topDocs.scoreDocs[4]).fields[0]).intValue(), equalTo(3));
|
||||||
|
assertThat(topDocs.scoreDocs[5].doc, equalTo(7));
|
||||||
|
assertThat(((Number) ((FieldDoc) topDocs.scoreDocs[5]).fields[0]).intValue(), equalTo(-9));
|
||||||
|
assertThat(topDocs.scoreDocs[6].doc, equalTo(1));
|
||||||
|
// assertThat(((FieldDoc) topDocs.scoreDocs[6]).fields[0], equalTo(null));
|
||||||
|
assertThat(topDocs.scoreDocs[7].doc, equalTo(5));
|
||||||
|
// assertThat(((FieldDoc) topDocs.scoreDocs[7]).fields[0], equalTo(null));
|
||||||
|
|
||||||
|
topDocs = searcher.search(new MatchAllDocsQuery(), 10,
|
||||||
|
new Sort(new SortField("value", indexFieldData.comparatorSource("_first", SortMode.MIN))));
|
||||||
assertThat(topDocs.totalHits, equalTo(8));
|
assertThat(topDocs.totalHits, equalTo(8));
|
||||||
assertThat(topDocs.scoreDocs.length, equalTo(8));
|
assertThat(topDocs.scoreDocs.length, equalTo(8));
|
||||||
assertThat(topDocs.scoreDocs[0].doc, equalTo(1));
|
assertThat(topDocs.scoreDocs[0].doc, equalTo(1));
|
||||||
@ -665,7 +755,7 @@ public abstract class NumericFieldDataTests extends StringFieldDataTests {
|
|||||||
assertThat(topDocs.scoreDocs[7].doc, equalTo(6));
|
assertThat(topDocs.scoreDocs[7].doc, equalTo(6));
|
||||||
|
|
||||||
topDocs = searcher.search(new MatchAllDocsQuery(), 10,
|
topDocs = searcher.search(new MatchAllDocsQuery(), 10,
|
||||||
new Sort(new SortField("value", indexFieldData.comparatorSource("_first"), true)));
|
new Sort(new SortField("value", indexFieldData.comparatorSource("_first", SortMode.MAX), true)));
|
||||||
assertThat(topDocs.totalHits, equalTo(8));
|
assertThat(topDocs.totalHits, equalTo(8));
|
||||||
assertThat(topDocs.scoreDocs.length, equalTo(8));
|
assertThat(topDocs.scoreDocs.length, equalTo(8));
|
||||||
assertThat(topDocs.scoreDocs[0].doc, equalTo(1));
|
assertThat(topDocs.scoreDocs[0].doc, equalTo(1));
|
||||||
@ -678,7 +768,7 @@ public abstract class NumericFieldDataTests extends StringFieldDataTests {
|
|||||||
assertThat(topDocs.scoreDocs[7].doc, equalTo(7));
|
assertThat(topDocs.scoreDocs[7].doc, equalTo(7));
|
||||||
|
|
||||||
topDocs = searcher.search(new MatchAllDocsQuery(), 10,
|
topDocs = searcher.search(new MatchAllDocsQuery(), 10,
|
||||||
new Sort(new SortField("value", indexFieldData.comparatorSource("-9"))));
|
new Sort(new SortField("value", indexFieldData.comparatorSource("-9", SortMode.MIN))));
|
||||||
assertThat(topDocs.totalHits, equalTo(8));
|
assertThat(topDocs.totalHits, equalTo(8));
|
||||||
assertThat(topDocs.scoreDocs.length, equalTo(8));
|
assertThat(topDocs.scoreDocs.length, equalTo(8));
|
||||||
assertThat(topDocs.scoreDocs[0].doc, equalTo(7));
|
assertThat(topDocs.scoreDocs[0].doc, equalTo(7));
|
||||||
@ -691,7 +781,7 @@ public abstract class NumericFieldDataTests extends StringFieldDataTests {
|
|||||||
assertThat(topDocs.scoreDocs[7].doc, equalTo(6));
|
assertThat(topDocs.scoreDocs[7].doc, equalTo(6));
|
||||||
|
|
||||||
topDocs = searcher.search(new MatchAllDocsQuery(), 10,
|
topDocs = searcher.search(new MatchAllDocsQuery(), 10,
|
||||||
new Sort(new SortField("value", indexFieldData.comparatorSource("9"), true)));
|
new Sort(new SortField("value", indexFieldData.comparatorSource("9", SortMode.MAX), true)));
|
||||||
assertThat(topDocs.totalHits, equalTo(8));
|
assertThat(topDocs.totalHits, equalTo(8));
|
||||||
assertThat(topDocs.scoreDocs.length, equalTo(8));
|
assertThat(topDocs.scoreDocs.length, equalTo(8));
|
||||||
assertThat(topDocs.scoreDocs[0].doc, equalTo(6));
|
assertThat(topDocs.scoreDocs[0].doc, equalTo(6));
|
||||||
|
@ -28,6 +28,7 @@ import org.apache.lucene.search.*;
|
|||||||
import org.apache.lucene.util.BytesRef;
|
import org.apache.lucene.util.BytesRef;
|
||||||
import org.elasticsearch.common.lucene.HashedBytesRef;
|
import org.elasticsearch.common.lucene.HashedBytesRef;
|
||||||
import org.elasticsearch.index.fielddata.*;
|
import org.elasticsearch.index.fielddata.*;
|
||||||
|
import org.elasticsearch.index.fielddata.fieldcomparator.SortMode;
|
||||||
import org.elasticsearch.index.fielddata.util.BytesRefArrayRef;
|
import org.elasticsearch.index.fielddata.util.BytesRefArrayRef;
|
||||||
import org.elasticsearch.index.fielddata.util.StringArrayRef;
|
import org.elasticsearch.index.fielddata.util.StringArrayRef;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
@ -197,7 +198,7 @@ public abstract class StringFieldDataTests extends AbstractFieldDataTests {
|
|||||||
TopFieldDocs topDocs;
|
TopFieldDocs topDocs;
|
||||||
|
|
||||||
topDocs = searcher.search(new MatchAllDocsQuery(), 10,
|
topDocs = searcher.search(new MatchAllDocsQuery(), 10,
|
||||||
new Sort(new SortField("value", indexFieldData.comparatorSource(null))));
|
new Sort(new SortField("value", indexFieldData.comparatorSource(null, SortMode.MIN))));
|
||||||
assertThat(topDocs.totalHits, equalTo(3));
|
assertThat(topDocs.totalHits, equalTo(3));
|
||||||
assertThat(topDocs.scoreDocs[0].doc, equalTo(1));
|
assertThat(topDocs.scoreDocs[0].doc, equalTo(1));
|
||||||
assertThat(toString(((FieldDoc) topDocs.scoreDocs[0]).fields[0]), equalTo(one()));
|
assertThat(toString(((FieldDoc) topDocs.scoreDocs[0]).fields[0]), equalTo(one()));
|
||||||
@ -207,7 +208,7 @@ public abstract class StringFieldDataTests extends AbstractFieldDataTests {
|
|||||||
assertThat(toString(((FieldDoc) topDocs.scoreDocs[2]).fields[0]), equalTo(three()));
|
assertThat(toString(((FieldDoc) topDocs.scoreDocs[2]).fields[0]), equalTo(three()));
|
||||||
|
|
||||||
topDocs = searcher.search(new MatchAllDocsQuery(), 10,
|
topDocs = searcher.search(new MatchAllDocsQuery(), 10,
|
||||||
new Sort(new SortField("value", indexFieldData.comparatorSource(null), true)));
|
new Sort(new SortField("value", indexFieldData.comparatorSource(null, SortMode.MAX), true)));
|
||||||
assertThat(topDocs.totalHits, equalTo(3));
|
assertThat(topDocs.totalHits, equalTo(3));
|
||||||
assertThat(topDocs.scoreDocs[0].doc, equalTo(2));
|
assertThat(topDocs.scoreDocs[0].doc, equalTo(2));
|
||||||
assertThat(topDocs.scoreDocs[1].doc, equalTo(0));
|
assertThat(topDocs.scoreDocs[1].doc, equalTo(0));
|
||||||
@ -487,14 +488,14 @@ public abstract class StringFieldDataTests extends AbstractFieldDataTests {
|
|||||||
stringValues.forEachValueInDoc(2, new StringValuesVerifierProc(2).addExpected(three()));
|
stringValues.forEachValueInDoc(2, new StringValuesVerifierProc(2).addExpected(three()));
|
||||||
|
|
||||||
IndexSearcher searcher = new IndexSearcher(DirectoryReader.open(writer, true));
|
IndexSearcher searcher = new IndexSearcher(DirectoryReader.open(writer, true));
|
||||||
TopFieldDocs topDocs = searcher.search(new MatchAllDocsQuery(), 10, new Sort(new SortField("value", indexFieldData.comparatorSource(null))));
|
TopFieldDocs topDocs = searcher.search(new MatchAllDocsQuery(), 10, new Sort(new SortField("value", indexFieldData.comparatorSource(null, SortMode.MIN))));
|
||||||
assertThat(topDocs.totalHits, equalTo(3));
|
assertThat(topDocs.totalHits, equalTo(3));
|
||||||
assertThat(topDocs.scoreDocs.length, equalTo(3));
|
assertThat(topDocs.scoreDocs.length, equalTo(3));
|
||||||
assertThat(topDocs.scoreDocs[0].doc, equalTo(1));
|
assertThat(topDocs.scoreDocs[0].doc, equalTo(1));
|
||||||
assertThat(topDocs.scoreDocs[1].doc, equalTo(0));
|
assertThat(topDocs.scoreDocs[1].doc, equalTo(0));
|
||||||
assertThat(topDocs.scoreDocs[2].doc, equalTo(2));
|
assertThat(topDocs.scoreDocs[2].doc, equalTo(2));
|
||||||
|
|
||||||
topDocs = searcher.search(new MatchAllDocsQuery(), 10, new Sort(new SortField("value", indexFieldData.comparatorSource(null), true)));
|
topDocs = searcher.search(new MatchAllDocsQuery(), 10, new Sort(new SortField("value", indexFieldData.comparatorSource(null, SortMode.MAX), true)));
|
||||||
assertThat(topDocs.totalHits, equalTo(3));
|
assertThat(topDocs.totalHits, equalTo(3));
|
||||||
assertThat(topDocs.scoreDocs.length, equalTo(3));
|
assertThat(topDocs.scoreDocs.length, equalTo(3));
|
||||||
assertThat(topDocs.scoreDocs[0].doc, equalTo(0));
|
assertThat(topDocs.scoreDocs[0].doc, equalTo(0));
|
||||||
@ -770,7 +771,7 @@ public abstract class StringFieldDataTests extends AbstractFieldDataTests {
|
|||||||
|
|
||||||
IndexSearcher searcher = new IndexSearcher(DirectoryReader.open(writer, true));
|
IndexSearcher searcher = new IndexSearcher(DirectoryReader.open(writer, true));
|
||||||
TopFieldDocs topDocs = searcher.search(new MatchAllDocsQuery(), 10,
|
TopFieldDocs topDocs = searcher.search(new MatchAllDocsQuery(), 10,
|
||||||
new Sort(new SortField("value", indexFieldData.comparatorSource(null))));
|
new Sort(new SortField("value", indexFieldData.comparatorSource(null, SortMode.MIN))));
|
||||||
assertThat(topDocs.totalHits, equalTo(8));
|
assertThat(topDocs.totalHits, equalTo(8));
|
||||||
assertThat(topDocs.scoreDocs.length, equalTo(8));
|
assertThat(topDocs.scoreDocs.length, equalTo(8));
|
||||||
assertThat(topDocs.scoreDocs[0].doc, equalTo(1));
|
assertThat(topDocs.scoreDocs[0].doc, equalTo(1));
|
||||||
@ -791,7 +792,7 @@ public abstract class StringFieldDataTests extends AbstractFieldDataTests {
|
|||||||
assertThat(((BytesRef) ((FieldDoc) topDocs.scoreDocs[7]).fields[0]).utf8ToString(), equalTo("08"));
|
assertThat(((BytesRef) ((FieldDoc) topDocs.scoreDocs[7]).fields[0]).utf8ToString(), equalTo("08"));
|
||||||
|
|
||||||
topDocs = searcher.search(new MatchAllDocsQuery(), 10,
|
topDocs = searcher.search(new MatchAllDocsQuery(), 10,
|
||||||
new Sort(new SortField("value", indexFieldData.comparatorSource(null), true)));
|
new Sort(new SortField("value", indexFieldData.comparatorSource(null, SortMode.MAX), true)));
|
||||||
assertThat(topDocs.totalHits, equalTo(8));
|
assertThat(topDocs.totalHits, equalTo(8));
|
||||||
assertThat(topDocs.scoreDocs.length, equalTo(8));
|
assertThat(topDocs.scoreDocs.length, equalTo(8));
|
||||||
assertThat(topDocs.scoreDocs[0].doc, equalTo(6));
|
assertThat(topDocs.scoreDocs[0].doc, equalTo(6));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user