Skip to content

Commit 700a2a9

Browse files
committed
Sort: Support "missing" specific handling, include _last, _first, and custom value (for numeric values), closes elastic#772.
1 parent 7c04ef6 commit 700a2a9

22 files changed

+775
-20
lines changed

modules/elasticsearch/src/main/java/org/elasticsearch/index/field/data/FieldDataType.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
import org.apache.lucene.index.IndexReader;
2323
import org.apache.lucene.search.FieldComparatorSource;
24+
import org.elasticsearch.common.Nullable;
2425
import org.elasticsearch.index.cache.field.data.FieldDataCache;
2526
import org.elasticsearch.index.field.data.bytes.ByteFieldDataType;
2627
import org.elasticsearch.index.field.data.doubles.DoubleFieldDataType;
@@ -47,7 +48,7 @@ public static final class DefaultTypes {
4748
public static final DoubleFieldDataType DOUBLE = new DoubleFieldDataType();
4849
}
4950

50-
FieldComparatorSource newFieldComparatorSource(FieldDataCache cache);
51+
FieldComparatorSource newFieldComparatorSource(FieldDataCache cache, @Nullable String missing);
5152

5253
T load(IndexReader reader, String fieldName) throws IOException;
5354
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
* Licensed to Elastic Search and Shay Banon under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. Elastic Search licenses this
6+
* file to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.elasticsearch.index.field.data.bytes;
21+
22+
import org.elasticsearch.index.cache.field.data.FieldDataCache;
23+
import org.elasticsearch.index.field.data.FieldDataType;
24+
import org.elasticsearch.index.field.data.support.NumericFieldDataComparator;
25+
26+
/**
27+
* @author kimchy (shay.banon)
28+
*/
29+
// LUCENE MONITOR: Monitor against FieldComparator.Short
30+
public class ByteFieldDataMissingComparator extends NumericFieldDataComparator {
31+
32+
private final byte[] values;
33+
private short bottom;
34+
private final byte missingValue;
35+
36+
public ByteFieldDataMissingComparator(int numHits, String fieldName, FieldDataCache fieldDataCache, byte missingValue) {
37+
super(fieldName, fieldDataCache);
38+
values = new byte[numHits];
39+
this.missingValue = missingValue;
40+
}
41+
42+
@Override public FieldDataType fieldDataType() {
43+
return FieldDataType.DefaultTypes.BYTE;
44+
}
45+
46+
@Override public int compare(int slot1, int slot2) {
47+
return values[slot1] - values[slot2];
48+
}
49+
50+
@Override public int compareBottom(int doc) {
51+
byte value = missingValue;
52+
if (currentFieldData.hasValue(doc)) {
53+
value = currentFieldData.byteValue(doc);
54+
}
55+
return bottom - value;
56+
}
57+
58+
@Override public void copy(int slot, int doc) {
59+
byte value = missingValue;
60+
if (currentFieldData.hasValue(doc)) {
61+
value = currentFieldData.byteValue(doc);
62+
}
63+
values[slot] = value;
64+
}
65+
66+
@Override public void setBottom(final int bottom) {
67+
this.bottom = values[bottom];
68+
}
69+
70+
@Override public Comparable value(int slot) {
71+
return Byte.valueOf(values[slot]);
72+
}
73+
}

modules/elasticsearch/src/main/java/org/elasticsearch/index/field/data/bytes/ByteFieldDataType.java

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,31 @@
3232
*/
3333
public class ByteFieldDataType implements FieldDataType<ByteFieldData> {
3434

35-
@Override public FieldComparatorSource newFieldComparatorSource(final FieldDataCache cache) {
35+
@Override public FieldComparatorSource newFieldComparatorSource(final FieldDataCache cache, final String missing) {
36+
if (missing == null) {
37+
return new FieldComparatorSource() {
38+
@Override public FieldComparator newComparator(String fieldname, int numHits, int sortPos, boolean reversed) throws IOException {
39+
return new ByteFieldDataComparator(numHits, fieldname, cache);
40+
}
41+
};
42+
}
43+
if (missing.equals("_last")) {
44+
return new FieldComparatorSource() {
45+
@Override public FieldComparator newComparator(String fieldname, int numHits, int sortPos, boolean reversed) throws IOException {
46+
return new ByteFieldDataMissingComparator(numHits, fieldname, cache, reversed ? Byte.MIN_VALUE : Byte.MAX_VALUE);
47+
}
48+
};
49+
}
50+
if (missing.equals("_first")) {
51+
return new FieldComparatorSource() {
52+
@Override public FieldComparator newComparator(String fieldname, int numHits, int sortPos, boolean reversed) throws IOException {
53+
return new ByteFieldDataMissingComparator(numHits, fieldname, cache, reversed ? Byte.MAX_VALUE : Byte.MIN_VALUE);
54+
}
55+
};
56+
}
3657
return new FieldComparatorSource() {
3758
@Override public FieldComparator newComparator(String fieldname, int numHits, int sortPos, boolean reversed) throws IOException {
38-
return new ByteFieldDataComparator(numHits, fieldname, cache);
59+
return new ByteFieldDataMissingComparator(numHits, fieldname, cache, Byte.parseByte(missing));
3960
}
4061
};
4162
}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/*
2+
* Licensed to Elastic Search and Shay Banon under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. Elastic Search licenses this
6+
* file to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.elasticsearch.index.field.data.doubles;
21+
22+
import org.elasticsearch.index.cache.field.data.FieldDataCache;
23+
import org.elasticsearch.index.field.data.FieldDataType;
24+
import org.elasticsearch.index.field.data.support.NumericFieldDataComparator;
25+
26+
/**
27+
* @author kimchy (shay.banon)
28+
*/
29+
// LUCENE MONITOR: Monitor against FieldComparator.Double
30+
public class DoubleFieldDataMissingComparator extends NumericFieldDataComparator {
31+
32+
private final double[] values;
33+
private double bottom;
34+
private final double missingValue;
35+
36+
public DoubleFieldDataMissingComparator(int numHits, String fieldName, FieldDataCache fieldDataCache, double missingValue) {
37+
super(fieldName, fieldDataCache);
38+
values = new double[numHits];
39+
this.missingValue = missingValue;
40+
}
41+
42+
@Override public FieldDataType fieldDataType() {
43+
return FieldDataType.DefaultTypes.DOUBLE;
44+
}
45+
46+
@Override public int compare(int slot1, int slot2) {
47+
final double v1 = values[slot1];
48+
final double v2 = values[slot2];
49+
if (v1 > v2) {
50+
return 1;
51+
} else if (v1 < v2) {
52+
return -1;
53+
} else {
54+
return 0;
55+
}
56+
}
57+
58+
@Override public int compareBottom(int doc) {
59+
double v2 = missingValue;
60+
if (currentFieldData.hasValue(doc)) {
61+
v2 = currentFieldData.doubleValue(doc);
62+
}
63+
if (bottom > v2) {
64+
return 1;
65+
} else if (bottom < v2) {
66+
return -1;
67+
} else {
68+
return 0;
69+
}
70+
}
71+
72+
@Override public void copy(int slot, int doc) {
73+
double value = missingValue;
74+
if (currentFieldData.hasValue(doc)) {
75+
value = currentFieldData.doubleValue(doc);
76+
}
77+
values[slot] = value;
78+
}
79+
80+
@Override public void setBottom(final int bottom) {
81+
this.bottom = values[bottom];
82+
}
83+
84+
@Override public Comparable value(int slot) {
85+
return Double.valueOf(values[slot]);
86+
}
87+
}

modules/elasticsearch/src/main/java/org/elasticsearch/index/field/data/doubles/DoubleFieldDataType.java

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,31 @@
3232
*/
3333
public class DoubleFieldDataType implements FieldDataType<DoubleFieldData> {
3434

35-
@Override public FieldComparatorSource newFieldComparatorSource(final FieldDataCache cache) {
35+
@Override public FieldComparatorSource newFieldComparatorSource(final FieldDataCache cache, final String missing) {
36+
if (missing == null) {
37+
return new FieldComparatorSource() {
38+
@Override public FieldComparator newComparator(String fieldname, int numHits, int sortPos, boolean reversed) throws IOException {
39+
return new DoubleFieldDataComparator(numHits, fieldname, cache);
40+
}
41+
};
42+
}
43+
if (missing.equals("_last")) {
44+
return new FieldComparatorSource() {
45+
@Override public FieldComparator newComparator(String fieldname, int numHits, int sortPos, boolean reversed) throws IOException {
46+
return new DoubleFieldDataMissingComparator(numHits, fieldname, cache, reversed ? Double.MIN_VALUE : Double.MAX_VALUE);
47+
}
48+
};
49+
}
50+
if (missing.equals("_first")) {
51+
return new FieldComparatorSource() {
52+
@Override public FieldComparator newComparator(String fieldname, int numHits, int sortPos, boolean reversed) throws IOException {
53+
return new DoubleFieldDataMissingComparator(numHits, fieldname, cache, reversed ? Double.MAX_VALUE : Double.MIN_VALUE);
54+
}
55+
};
56+
}
3657
return new FieldComparatorSource() {
3758
@Override public FieldComparator newComparator(String fieldname, int numHits, int sortPos, boolean reversed) throws IOException {
38-
return new DoubleFieldDataComparator(numHits, fieldname, cache);
59+
return new DoubleFieldDataMissingComparator(numHits, fieldname, cache, Double.parseDouble(missing));
3960
}
4061
};
4162
}
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
/*
2+
* Licensed to Elastic Search and Shay Banon under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. Elastic Search licenses this
6+
* file to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.elasticsearch.index.field.data.floats;
21+
22+
import org.elasticsearch.index.cache.field.data.FieldDataCache;
23+
import org.elasticsearch.index.field.data.FieldDataType;
24+
import org.elasticsearch.index.field.data.support.NumericFieldDataComparator;
25+
26+
/**
27+
* @author kimchy (shay.banon)
28+
*/
29+
// LUCENE MONITOR - Monitor against FieldComparator.Float
30+
public class FloatFieldDataMissingComparator extends NumericFieldDataComparator {
31+
32+
private final float[] values;
33+
private float bottom;
34+
private final float missingValue;
35+
36+
public FloatFieldDataMissingComparator(int numHits, String fieldName, FieldDataCache fieldDataCache, float missingValue) {
37+
super(fieldName, fieldDataCache);
38+
values = new float[numHits];
39+
this.missingValue = missingValue;
40+
}
41+
42+
@Override public FieldDataType fieldDataType() {
43+
return FieldDataType.DefaultTypes.FLOAT;
44+
}
45+
46+
@Override public int compare(int slot1, int slot2) {
47+
// TODO: are there sneaky non-branch ways to compute
48+
// sign of float?
49+
final float v1 = values[slot1];
50+
final float v2 = values[slot2];
51+
if (v1 > v2) {
52+
return 1;
53+
} else if (v1 < v2) {
54+
return -1;
55+
} else {
56+
return 0;
57+
}
58+
}
59+
60+
@Override public int compareBottom(int doc) {
61+
// TODO: are there sneaky non-branch ways to compute
62+
// sign of float?
63+
float v2 = missingValue;
64+
if (currentFieldData.hasValue(doc)) {
65+
v2 = currentFieldData.floatValue(doc);
66+
}
67+
if (bottom > v2) {
68+
return 1;
69+
} else if (bottom < v2) {
70+
return -1;
71+
} else {
72+
return 0;
73+
}
74+
}
75+
76+
@Override
77+
public void copy(int slot, int doc) {
78+
float value = missingValue;
79+
if (currentFieldData.hasValue(doc)) {
80+
value = currentFieldData.floatValue(doc);
81+
}
82+
values[slot] = value;
83+
}
84+
85+
@Override public void setBottom(final int bottom) {
86+
this.bottom = values[bottom];
87+
}
88+
89+
@Override public Comparable value(int slot) {
90+
return Float.valueOf(values[slot]);
91+
}
92+
}

modules/elasticsearch/src/main/java/org/elasticsearch/index/field/data/floats/FloatFieldDataType.java

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,31 @@
3232
*/
3333
public class FloatFieldDataType implements FieldDataType<FloatFieldData> {
3434

35-
@Override public FieldComparatorSource newFieldComparatorSource(final FieldDataCache cache) {
35+
@Override public FieldComparatorSource newFieldComparatorSource(final FieldDataCache cache, final String missing) {
36+
if (missing == null) {
37+
return new FieldComparatorSource() {
38+
@Override public FieldComparator newComparator(String fieldname, int numHits, int sortPos, boolean reversed) throws IOException {
39+
return new FloatFieldDataComparator(numHits, fieldname, cache);
40+
}
41+
};
42+
}
43+
if (missing.equals("_last")) {
44+
return new FieldComparatorSource() {
45+
@Override public FieldComparator newComparator(String fieldname, int numHits, int sortPos, boolean reversed) throws IOException {
46+
return new FloatFieldDataMissingComparator(numHits, fieldname, cache, reversed ? Float.MIN_VALUE : Float.MAX_VALUE);
47+
}
48+
};
49+
}
50+
if (missing.equals("_first")) {
51+
return new FieldComparatorSource() {
52+
@Override public FieldComparator newComparator(String fieldname, int numHits, int sortPos, boolean reversed) throws IOException {
53+
return new FloatFieldDataMissingComparator(numHits, fieldname, cache, reversed ? Float.MAX_VALUE : Float.MIN_VALUE);
54+
}
55+
};
56+
}
3657
return new FieldComparatorSource() {
3758
@Override public FieldComparator newComparator(String fieldname, int numHits, int sortPos, boolean reversed) throws IOException {
38-
return new FloatFieldDataComparator(numHits, fieldname, cache);
59+
return new FloatFieldDataMissingComparator(numHits, fieldname, cache, Float.parseFloat(missing));
3960
}
4061
};
4162
}

0 commit comments

Comments
 (0)