move sorting to be done using the new fielddata cache, and not using lucene built in FieldCache
This commit is contained in:
parent
97b5b41522
commit
8d669ff54e
|
@ -64,7 +64,7 @@ public abstract class AbstractConcurrentMapFieldDataCache extends AbstractIndexC
|
|||
}
|
||||
|
||||
@Override public FieldData cache(FieldData.Type type, IndexReader reader, String fieldName) throws IOException {
|
||||
return cache(type.fieldDataClass, reader, fieldName);
|
||||
return cache(type.fieldDataClass(), reader, fieldName);
|
||||
}
|
||||
|
||||
@Override public <T extends FieldData> T cache(Class<T> type, IndexReader reader, String fieldName) throws IOException {
|
||||
|
|
|
@ -20,14 +20,23 @@
|
|||
package org.elasticsearch.index.field.data;
|
||||
|
||||
import org.apache.lucene.index.IndexReader;
|
||||
import org.apache.lucene.search.FieldComparator;
|
||||
import org.apache.lucene.search.FieldComparatorSource;
|
||||
import org.elasticsearch.ElasticSearchIllegalArgumentException;
|
||||
import org.elasticsearch.common.thread.ThreadLocals;
|
||||
import org.elasticsearch.index.cache.field.data.FieldDataCache;
|
||||
import org.elasticsearch.index.field.data.doubles.DoubleFieldData;
|
||||
import org.elasticsearch.index.field.data.doubles.DoubleFieldDataComparator;
|
||||
import org.elasticsearch.index.field.data.floats.FloatFieldData;
|
||||
import org.elasticsearch.index.field.data.floats.FloatFieldDataComparator;
|
||||
import org.elasticsearch.index.field.data.ints.IntFieldData;
|
||||
import org.elasticsearch.index.field.data.ints.IntFieldDataComparator;
|
||||
import org.elasticsearch.index.field.data.longs.LongFieldData;
|
||||
import org.elasticsearch.index.field.data.longs.LongFieldDataComparator;
|
||||
import org.elasticsearch.index.field.data.shorts.ShortFieldData;
|
||||
import org.elasticsearch.index.field.data.shorts.ShortFieldDataComparator;
|
||||
import org.elasticsearch.index.field.data.strings.StringFieldData;
|
||||
import org.elasticsearch.index.field.data.strings.StringOrdValFieldDataComparator;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
|
@ -39,25 +48,109 @@ import java.io.IOException;
|
|||
public abstract class FieldData<Doc extends DocFieldData> {
|
||||
|
||||
public static enum Type {
|
||||
STRING(StringFieldData.class, false),
|
||||
SHORT(ShortFieldData.class, true),
|
||||
INT(IntFieldData.class, true),
|
||||
LONG(LongFieldData.class, true),
|
||||
FLOAT(FloatFieldData.class, true),
|
||||
DOUBLE(DoubleFieldData.class, true);
|
||||
STRING() {
|
||||
|
||||
public final Class<? extends FieldData> fieldDataClass;
|
||||
@Override public Class<? extends FieldData> fieldDataClass() {
|
||||
return StringFieldData.class;
|
||||
}
|
||||
|
||||
private final boolean isNumeric;
|
||||
@Override public boolean isNumeric() {
|
||||
return false;
|
||||
}
|
||||
|
||||
Type(Class<? extends FieldData> clazz, boolean numeric) {
|
||||
this.fieldDataClass = clazz;
|
||||
this.isNumeric = numeric;
|
||||
}
|
||||
@Override public FieldComparatorSource newFieldComparatorSource(final FieldDataCache cache) {
|
||||
return new FieldComparatorSource() {
|
||||
@Override public FieldComparator newComparator(String fieldname, int numHits, int sortPos, boolean reversed) throws IOException {
|
||||
return new StringOrdValFieldDataComparator(numHits, fieldname, sortPos, reversed, cache);
|
||||
}
|
||||
};
|
||||
}},
|
||||
SHORT() {
|
||||
@Override public Class<? extends FieldData> fieldDataClass() {
|
||||
return ShortFieldData.class;
|
||||
}
|
||||
|
||||
public boolean isNumeric() {
|
||||
return isNumeric;
|
||||
}
|
||||
@Override public boolean isNumeric() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override public FieldComparatorSource newFieldComparatorSource(final FieldDataCache cache) {
|
||||
return new FieldComparatorSource() {
|
||||
@Override public FieldComparator newComparator(String fieldname, int numHits, int sortPos, boolean reversed) throws IOException {
|
||||
return new ShortFieldDataComparator(numHits, fieldname, cache);
|
||||
}
|
||||
};
|
||||
}},
|
||||
INT() {
|
||||
@Override public Class<? extends FieldData> fieldDataClass() {
|
||||
return IntFieldData.class;
|
||||
}
|
||||
|
||||
@Override public boolean isNumeric() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override public FieldComparatorSource newFieldComparatorSource(final FieldDataCache cache) {
|
||||
return new FieldComparatorSource() {
|
||||
@Override public FieldComparator newComparator(String fieldname, int numHits, int sortPos, boolean reversed) throws IOException {
|
||||
return new IntFieldDataComparator(numHits, fieldname, cache);
|
||||
}
|
||||
};
|
||||
}},
|
||||
LONG() {
|
||||
@Override public Class<? extends FieldData> fieldDataClass() {
|
||||
return LongFieldData.class;
|
||||
}
|
||||
|
||||
@Override public boolean isNumeric() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override public FieldComparatorSource newFieldComparatorSource(final FieldDataCache cache) {
|
||||
return new FieldComparatorSource() {
|
||||
@Override public FieldComparator newComparator(String fieldname, int numHits, int sortPos, boolean reversed) throws IOException {
|
||||
return new LongFieldDataComparator(numHits, fieldname, cache);
|
||||
}
|
||||
};
|
||||
}},
|
||||
FLOAT() {
|
||||
@Override public Class<? extends FieldData> fieldDataClass() {
|
||||
return FloatFieldData.class;
|
||||
}
|
||||
|
||||
@Override public boolean isNumeric() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override public FieldComparatorSource newFieldComparatorSource(final FieldDataCache cache) {
|
||||
return new FieldComparatorSource() {
|
||||
@Override public FieldComparator newComparator(String fieldname, int numHits, int sortPos, boolean reversed) throws IOException {
|
||||
return new FloatFieldDataComparator(numHits, fieldname, cache);
|
||||
}
|
||||
};
|
||||
}},
|
||||
DOUBLE() {
|
||||
@Override public Class<? extends FieldData> fieldDataClass() {
|
||||
return DoubleFieldData.class;
|
||||
}
|
||||
|
||||
@Override public boolean isNumeric() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override public FieldComparatorSource newFieldComparatorSource(final FieldDataCache cache) {
|
||||
return new FieldComparatorSource() {
|
||||
@Override public FieldComparator newComparator(String fieldname, int numHits, int sortPos, boolean reversed) throws IOException {
|
||||
return new DoubleFieldDataComparator(numHits, fieldname, cache);
|
||||
}
|
||||
};
|
||||
}};
|
||||
|
||||
public abstract Class<? extends FieldData> fieldDataClass();
|
||||
|
||||
public abstract boolean isNumeric();
|
||||
|
||||
public abstract FieldComparatorSource newFieldComparatorSource(FieldDataCache cache);
|
||||
}
|
||||
|
||||
private final ThreadLocal<ThreadLocals.CleanableValue<Doc>> cachedDocFieldData = new ThreadLocal<ThreadLocals.CleanableValue<Doc>>() {
|
||||
|
@ -116,8 +209,10 @@ public abstract class FieldData<Doc extends DocFieldData> {
|
|||
*/
|
||||
public abstract Type type();
|
||||
|
||||
public abstract FieldComparator newComparator(FieldDataCache fieldDataCache, int numHits, String field, int sortPos, boolean reversed);
|
||||
|
||||
public static FieldData load(Type type, IndexReader reader, String fieldName) throws IOException {
|
||||
return load(type.fieldDataClass, reader, fieldName);
|
||||
return load(type.fieldDataClass(), reader, fieldName);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
|
|
|
@ -21,7 +21,9 @@ package org.elasticsearch.index.field.data.doubles;
|
|||
|
||||
import org.apache.lucene.index.IndexReader;
|
||||
import org.apache.lucene.search.FieldCache;
|
||||
import org.apache.lucene.search.FieldComparator;
|
||||
import org.elasticsearch.common.trove.TDoubleArrayList;
|
||||
import org.elasticsearch.index.cache.field.data.FieldDataCache;
|
||||
import org.elasticsearch.index.field.data.NumericFieldData;
|
||||
import org.elasticsearch.index.field.data.support.FieldDataLoader;
|
||||
|
||||
|
@ -41,6 +43,10 @@ public abstract class DoubleFieldData extends NumericFieldData<DoubleDocFieldDat
|
|||
this.values = values;
|
||||
}
|
||||
|
||||
@Override public FieldComparator newComparator(FieldDataCache fieldDataCache, int numHits, String field, int sortPos, boolean reversed) {
|
||||
return new DoubleFieldDataComparator(numHits, field, fieldDataCache);
|
||||
}
|
||||
|
||||
abstract public double value(int docId);
|
||||
|
||||
abstract public double[] values(int docId);
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search 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.field.data.doubles;
|
||||
|
||||
import org.elasticsearch.index.cache.field.data.FieldDataCache;
|
||||
import org.elasticsearch.index.field.data.FieldData;
|
||||
import org.elasticsearch.index.field.data.support.NumericFieldDataComparator;
|
||||
|
||||
/**
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
public class DoubleFieldDataComparator extends NumericFieldDataComparator {
|
||||
|
||||
private final double[] values;
|
||||
private double bottom;
|
||||
|
||||
public DoubleFieldDataComparator(int numHits, String fieldName, FieldDataCache fieldDataCache) {
|
||||
super(fieldName, fieldDataCache);
|
||||
values = new double[numHits];
|
||||
}
|
||||
|
||||
@Override public FieldData.Type fieldDataType() {
|
||||
return FieldData.Type.DOUBLE;
|
||||
}
|
||||
|
||||
@Override public int compare(int slot1, int slot2) {
|
||||
final double v1 = values[slot1];
|
||||
final double v2 = values[slot2];
|
||||
if (v1 > v2) {
|
||||
return 1;
|
||||
} else if (v1 < v2) {
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override public int compareBottom(int doc) {
|
||||
final double v2 = currentFieldData.doubleValue(doc);
|
||||
if (bottom > v2) {
|
||||
return 1;
|
||||
} else if (bottom < v2) {
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void copy(int slot, int doc) {
|
||||
values[slot] = currentFieldData.doubleValue(doc);
|
||||
}
|
||||
|
||||
@Override public void setBottom(final int bottom) {
|
||||
this.bottom = values[bottom];
|
||||
}
|
||||
|
||||
@Override public Comparable value(int slot) {
|
||||
return Double.valueOf(values[slot]);
|
||||
}
|
||||
}
|
|
@ -21,7 +21,9 @@ package org.elasticsearch.index.field.data.floats;
|
|||
|
||||
import org.apache.lucene.index.IndexReader;
|
||||
import org.apache.lucene.search.FieldCache;
|
||||
import org.apache.lucene.search.FieldComparator;
|
||||
import org.elasticsearch.common.trove.TFloatArrayList;
|
||||
import org.elasticsearch.index.cache.field.data.FieldDataCache;
|
||||
import org.elasticsearch.index.field.data.NumericFieldData;
|
||||
import org.elasticsearch.index.field.data.support.FieldDataLoader;
|
||||
|
||||
|
@ -41,6 +43,10 @@ public abstract class FloatFieldData extends NumericFieldData<FloatDocFieldData>
|
|||
this.values = values;
|
||||
}
|
||||
|
||||
@Override public FieldComparator newComparator(FieldDataCache fieldDataCache, int numHits, String field, int sortPos, boolean reversed) {
|
||||
return new FloatFieldDataComparator(numHits, field, fieldDataCache);
|
||||
}
|
||||
|
||||
abstract public float value(int docId);
|
||||
|
||||
abstract public float[] values(int docId);
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search 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.field.data.floats;
|
||||
|
||||
import org.elasticsearch.index.cache.field.data.FieldDataCache;
|
||||
import org.elasticsearch.index.field.data.FieldData;
|
||||
import org.elasticsearch.index.field.data.support.NumericFieldDataComparator;
|
||||
|
||||
/**
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
// LUCENE MONITOR - Monitor against FieldComparator.Float
|
||||
public class FloatFieldDataComparator extends NumericFieldDataComparator {
|
||||
|
||||
private final float[] values;
|
||||
private float bottom;
|
||||
|
||||
public FloatFieldDataComparator(int numHits, String fieldName, FieldDataCache fieldDataCache) {
|
||||
super(fieldName, fieldDataCache);
|
||||
values = new float[numHits];
|
||||
}
|
||||
|
||||
@Override public FieldData.Type fieldDataType() {
|
||||
return FieldData.Type.FLOAT;
|
||||
}
|
||||
|
||||
@Override public int compare(int slot1, int slot2) {
|
||||
// TODO: are there sneaky non-branch ways to compute
|
||||
// sign of float?
|
||||
final float v1 = values[slot1];
|
||||
final float v2 = values[slot2];
|
||||
if (v1 > v2) {
|
||||
return 1;
|
||||
} else if (v1 < v2) {
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override public int compareBottom(int doc) {
|
||||
// TODO: are there sneaky non-branch ways to compute
|
||||
// sign of float?
|
||||
final float v2 = currentFieldData.floatValue(doc);
|
||||
if (bottom > v2) {
|
||||
return 1;
|
||||
} else if (bottom < v2) {
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void copy(int slot, int doc) {
|
||||
values[slot] = currentFieldData.floatValue(doc);
|
||||
}
|
||||
|
||||
@Override public void setBottom(final int bottom) {
|
||||
this.bottom = values[bottom];
|
||||
}
|
||||
|
||||
@Override public Comparable value(int slot) {
|
||||
return Float.valueOf(values[slot]);
|
||||
}
|
||||
}
|
|
@ -21,7 +21,9 @@ package org.elasticsearch.index.field.data.ints;
|
|||
|
||||
import org.apache.lucene.index.IndexReader;
|
||||
import org.apache.lucene.search.FieldCache;
|
||||
import org.apache.lucene.search.FieldComparator;
|
||||
import org.elasticsearch.common.trove.TIntArrayList;
|
||||
import org.elasticsearch.index.cache.field.data.FieldDataCache;
|
||||
import org.elasticsearch.index.field.data.NumericFieldData;
|
||||
import org.elasticsearch.index.field.data.support.FieldDataLoader;
|
||||
|
||||
|
@ -41,6 +43,10 @@ public abstract class IntFieldData extends NumericFieldData<IntDocFieldData> {
|
|||
this.values = values;
|
||||
}
|
||||
|
||||
@Override public FieldComparator newComparator(FieldDataCache fieldDataCache, int numHits, String field, int sortPos, boolean reversed) {
|
||||
return new IntFieldDataComparator(numHits, field, fieldDataCache);
|
||||
}
|
||||
|
||||
abstract public int value(int docId);
|
||||
|
||||
abstract public int[] values(int docId);
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search 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.field.data.ints;
|
||||
|
||||
import org.elasticsearch.index.cache.field.data.FieldDataCache;
|
||||
import org.elasticsearch.index.field.data.FieldData;
|
||||
import org.elasticsearch.index.field.data.support.NumericFieldDataComparator;
|
||||
|
||||
/**
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
// LUCENE MONITOR - Monitor against FieldComparator.Int
|
||||
public class IntFieldDataComparator extends NumericFieldDataComparator {
|
||||
|
||||
private final int[] values;
|
||||
|
||||
private int bottom; // Value of bottom of queue
|
||||
|
||||
public IntFieldDataComparator(int numHits, String fieldName, FieldDataCache fieldDataCache) {
|
||||
super(fieldName, fieldDataCache);
|
||||
values = new int[numHits];
|
||||
}
|
||||
|
||||
@Override public FieldData.Type fieldDataType() {
|
||||
return FieldData.Type.INT;
|
||||
}
|
||||
|
||||
@Override public int compare(int slot1, int slot2) {
|
||||
// TODO: there are sneaky non-branch ways to compute
|
||||
// -1/+1/0 sign
|
||||
// Cannot return values[slot1] - values[slot2] because that
|
||||
// may overflow
|
||||
final int v1 = values[slot1];
|
||||
final int v2 = values[slot2];
|
||||
if (v1 > v2) {
|
||||
return 1;
|
||||
} else if (v1 < v2) {
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override public int compareBottom(int doc) {
|
||||
// TODO: there are sneaky non-branch ways to compute
|
||||
// -1/+1/0 sign
|
||||
// Cannot return bottom - values[slot2] because that
|
||||
// may overflow
|
||||
// final int v2 = currentReaderValues[doc];
|
||||
final int v2 = currentFieldData.intValue(doc);
|
||||
if (bottom > v2) {
|
||||
return 1;
|
||||
} else if (bottom < v2) {
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void copy(int slot, int doc) {
|
||||
values[slot] = currentFieldData.intValue(doc);
|
||||
}
|
||||
|
||||
@Override public void setBottom(final int bottom) {
|
||||
this.bottom = values[bottom];
|
||||
}
|
||||
|
||||
@Override public Comparable value(int slot) {
|
||||
return Integer.valueOf(values[slot]);
|
||||
}
|
||||
}
|
|
@ -21,9 +21,11 @@ package org.elasticsearch.index.field.data.longs;
|
|||
|
||||
import org.apache.lucene.index.IndexReader;
|
||||
import org.apache.lucene.search.FieldCache;
|
||||
import org.apache.lucene.search.FieldComparator;
|
||||
import org.elasticsearch.common.joda.time.MutableDateTime;
|
||||
import org.elasticsearch.common.thread.ThreadLocals;
|
||||
import org.elasticsearch.common.trove.TLongArrayList;
|
||||
import org.elasticsearch.index.cache.field.data.FieldDataCache;
|
||||
import org.elasticsearch.index.field.data.NumericFieldData;
|
||||
import org.elasticsearch.index.field.data.support.FieldDataLoader;
|
||||
|
||||
|
@ -50,6 +52,10 @@ public abstract class LongFieldData extends NumericFieldData<LongDocFieldData> {
|
|||
this.values = values;
|
||||
}
|
||||
|
||||
@Override public FieldComparator newComparator(FieldDataCache fieldDataCache, int numHits, String field, int sortPos, boolean reversed) {
|
||||
return new LongFieldDataComparator(numHits, field, fieldDataCache);
|
||||
}
|
||||
|
||||
abstract public long value(int docId);
|
||||
|
||||
abstract public long[] values(int docId);
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search 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.field.data.longs;
|
||||
|
||||
import org.elasticsearch.index.cache.field.data.FieldDataCache;
|
||||
import org.elasticsearch.index.field.data.FieldData;
|
||||
import org.elasticsearch.index.field.data.support.NumericFieldDataComparator;
|
||||
|
||||
/**
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
// LUCENE MONITOR - Monitor against FieldComparator.Long
|
||||
public class LongFieldDataComparator extends NumericFieldDataComparator {
|
||||
|
||||
private final long[] values;
|
||||
private long bottom;
|
||||
|
||||
public LongFieldDataComparator(int numHits, String fieldName, FieldDataCache fieldDataCache) {
|
||||
super(fieldName, fieldDataCache);
|
||||
values = new long[numHits];
|
||||
}
|
||||
|
||||
@Override public FieldData.Type fieldDataType() {
|
||||
return FieldData.Type.LONG;
|
||||
}
|
||||
|
||||
@Override public int compare(int slot1, int slot2) {
|
||||
// TODO: there are sneaky non-branch ways to compute
|
||||
// -1/+1/0 sign
|
||||
final long v1 = values[slot1];
|
||||
final long v2 = values[slot2];
|
||||
if (v1 > v2) {
|
||||
return 1;
|
||||
} else if (v1 < v2) {
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareBottom(int doc) {
|
||||
// TODO: there are sneaky non-branch ways to compute
|
||||
// -1/+1/0 sign
|
||||
// final long v2 = currentReaderValues[doc];
|
||||
final long v2 = currentFieldData.longValue(doc);
|
||||
if (bottom > v2) {
|
||||
return 1;
|
||||
} else if (bottom < v2) {
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void copy(int slot, int doc) {
|
||||
values[slot] = currentFieldData.longValue(doc);
|
||||
}
|
||||
|
||||
@Override public void setBottom(final int bottom) {
|
||||
this.bottom = values[bottom];
|
||||
}
|
||||
|
||||
@Override public Comparable value(int slot) {
|
||||
return Long.valueOf(values[slot]);
|
||||
}
|
||||
|
||||
}
|
|
@ -21,7 +21,9 @@ package org.elasticsearch.index.field.data.shorts;
|
|||
|
||||
import org.apache.lucene.index.IndexReader;
|
||||
import org.apache.lucene.search.FieldCache;
|
||||
import org.apache.lucene.search.FieldComparator;
|
||||
import org.elasticsearch.common.trove.TShortArrayList;
|
||||
import org.elasticsearch.index.cache.field.data.FieldDataCache;
|
||||
import org.elasticsearch.index.field.data.NumericFieldData;
|
||||
import org.elasticsearch.index.field.data.support.FieldDataLoader;
|
||||
|
||||
|
@ -41,6 +43,10 @@ public abstract class ShortFieldData extends NumericFieldData<ShortDocFieldData>
|
|||
this.values = values;
|
||||
}
|
||||
|
||||
@Override public FieldComparator newComparator(FieldDataCache fieldDataCache, int numHits, String field, int sortPos, boolean reversed) {
|
||||
return new ShortFieldDataComparator(numHits, field, fieldDataCache);
|
||||
}
|
||||
|
||||
abstract public short value(int docId);
|
||||
|
||||
abstract public short[] values(int docId);
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search 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.field.data.shorts;
|
||||
|
||||
import org.elasticsearch.index.cache.field.data.FieldDataCache;
|
||||
import org.elasticsearch.index.field.data.FieldData;
|
||||
import org.elasticsearch.index.field.data.support.NumericFieldDataComparator;
|
||||
|
||||
/**
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
public class ShortFieldDataComparator extends NumericFieldDataComparator {
|
||||
|
||||
private final short[] values;
|
||||
private short bottom;
|
||||
|
||||
public ShortFieldDataComparator(int numHits, String fieldName, FieldDataCache fieldDataCache) {
|
||||
super(fieldName, fieldDataCache);
|
||||
values = new short[numHits];
|
||||
}
|
||||
|
||||
@Override public FieldData.Type fieldDataType() {
|
||||
return FieldData.Type.SHORT;
|
||||
}
|
||||
|
||||
@Override public int compare(int slot1, int slot2) {
|
||||
return values[slot1] - values[slot2];
|
||||
}
|
||||
|
||||
@Override public int compareBottom(int doc) {
|
||||
return bottom - currentFieldData.shortValue(doc);
|
||||
}
|
||||
|
||||
@Override public void copy(int slot, int doc) {
|
||||
values[slot] = currentFieldData.shortValue(doc);
|
||||
}
|
||||
|
||||
@Override public void setBottom(final int bottom) {
|
||||
this.bottom = values[bottom];
|
||||
}
|
||||
|
||||
@Override public Comparable value(int slot) {
|
||||
return Short.valueOf(values[slot]);
|
||||
}
|
||||
}
|
|
@ -19,8 +19,10 @@
|
|||
|
||||
package org.elasticsearch.index.field.data.strings;
|
||||
|
||||
import org.apache.lucene.search.FieldComparator;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.thread.ThreadLocals;
|
||||
import org.elasticsearch.index.cache.field.data.FieldDataCache;
|
||||
|
||||
/**
|
||||
* @author kimchy (shay.banon)
|
||||
|
@ -47,6 +49,10 @@ public class MultiValueStringFieldData extends StringFieldData {
|
|||
this.order = order;
|
||||
}
|
||||
|
||||
@Override public FieldComparator newComparator(FieldDataCache fieldDataCache, int numHits, String field, int sortPos, boolean reversed) {
|
||||
return new StringValFieldDataComparator(numHits, field, fieldDataCache);
|
||||
}
|
||||
|
||||
@Override public boolean multiValued() {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -19,8 +19,10 @@
|
|||
|
||||
package org.elasticsearch.index.field.data.strings;
|
||||
|
||||
import org.apache.lucene.search.FieldComparator;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.thread.ThreadLocals;
|
||||
import org.elasticsearch.index.cache.field.data.FieldDataCache;
|
||||
|
||||
/**
|
||||
* @author kimchy (shay.banon)
|
||||
|
@ -41,6 +43,18 @@ public class SingleValueStringFieldData extends StringFieldData {
|
|||
this.order = order;
|
||||
}
|
||||
|
||||
@Override public FieldComparator newComparator(FieldDataCache fieldDataCache, int numHits, String field, int sortPos, boolean reversed) {
|
||||
return new StringOrdValFieldDataComparator(numHits, field, sortPos, reversed, fieldDataCache);
|
||||
}
|
||||
|
||||
int[] order() {
|
||||
return order;
|
||||
}
|
||||
|
||||
String[] values() {
|
||||
return this.values;
|
||||
}
|
||||
|
||||
@Override public boolean multiValued() {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,180 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search 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.field.data.strings;
|
||||
|
||||
import org.apache.lucene.index.IndexReader;
|
||||
import org.apache.lucene.search.FieldComparator;
|
||||
import org.elasticsearch.index.cache.field.data.FieldDataCache;
|
||||
import org.elasticsearch.index.field.data.FieldData;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
public class StringOrdValFieldDataComparator extends FieldComparator {
|
||||
|
||||
private final FieldDataCache fieldDataCache;
|
||||
|
||||
private final int[] ords;
|
||||
private final String[] values;
|
||||
private final int[] readerGen;
|
||||
|
||||
private int currentReaderGen = -1;
|
||||
private String[] lookup;
|
||||
private int[] order;
|
||||
private final String field;
|
||||
|
||||
private int bottomSlot = -1;
|
||||
private int bottomOrd;
|
||||
private String bottomValue;
|
||||
private final boolean reversed;
|
||||
private final int sortPos;
|
||||
|
||||
public StringOrdValFieldDataComparator(int numHits, String field, int sortPos, boolean reversed, FieldDataCache fieldDataCache) {
|
||||
this.fieldDataCache = fieldDataCache;
|
||||
ords = new int[numHits];
|
||||
values = new String[numHits];
|
||||
readerGen = new int[numHits];
|
||||
this.sortPos = sortPos;
|
||||
this.reversed = reversed;
|
||||
this.field = field;
|
||||
}
|
||||
|
||||
@Override public int compare(int slot1, int slot2) {
|
||||
if (readerGen[slot1] == readerGen[slot2]) {
|
||||
int cmp = ords[slot1] - ords[slot2];
|
||||
if (cmp != 0) {
|
||||
return cmp;
|
||||
}
|
||||
}
|
||||
|
||||
final String val1 = values[slot1];
|
||||
final String val2 = values[slot2];
|
||||
if (val1 == null) {
|
||||
if (val2 == null) {
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
} else if (val2 == null) {
|
||||
return 1;
|
||||
}
|
||||
return val1.compareTo(val2);
|
||||
}
|
||||
|
||||
@Override public int compareBottom(int doc) {
|
||||
assert bottomSlot != -1;
|
||||
int order = this.order[doc];
|
||||
final int cmp = bottomOrd - order;
|
||||
if (cmp != 0) {
|
||||
return cmp;
|
||||
}
|
||||
|
||||
final String val2 = lookup[order];
|
||||
if (bottomValue == null) {
|
||||
if (val2 == null) {
|
||||
return 0;
|
||||
}
|
||||
// bottom wins
|
||||
return -1;
|
||||
} else if (val2 == null) {
|
||||
// doc wins
|
||||
return 1;
|
||||
}
|
||||
return bottomValue.compareTo(val2);
|
||||
}
|
||||
|
||||
private void convert(int slot) {
|
||||
readerGen[slot] = currentReaderGen;
|
||||
int index = 0;
|
||||
String value = values[slot];
|
||||
if (value == null) {
|
||||
ords[slot] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (sortPos == 0 && bottomSlot != -1 && bottomSlot != slot) {
|
||||
// Since we are the primary sort, the entries in the
|
||||
// queue are bounded by bottomOrd:
|
||||
assert bottomOrd < lookup.length;
|
||||
if (reversed) {
|
||||
index = binarySearch(lookup, value, bottomOrd, lookup.length - 1);
|
||||
} else {
|
||||
index = binarySearch(lookup, value, 0, bottomOrd);
|
||||
}
|
||||
} else {
|
||||
// Full binary search
|
||||
index = binarySearch(lookup, value);
|
||||
}
|
||||
|
||||
if (index < 0) {
|
||||
index = -index - 2;
|
||||
}
|
||||
ords[slot] = index;
|
||||
}
|
||||
|
||||
@Override public void copy(int slot, int doc) {
|
||||
final int ord = order[doc];
|
||||
ords[slot] = ord;
|
||||
assert ord >= 0;
|
||||
values[slot] = lookup[ord];
|
||||
readerGen[slot] = currentReaderGen;
|
||||
}
|
||||
|
||||
@Override public void setNextReader(IndexReader reader, int docBase) throws IOException {
|
||||
SingleValueStringFieldData fieldData = (SingleValueStringFieldData) fieldDataCache.cache(FieldData.Type.STRING, reader, field);
|
||||
currentReaderGen++;
|
||||
order = fieldData.order();
|
||||
lookup = fieldData.values();
|
||||
assert lookup.length > 0;
|
||||
if (bottomSlot != -1) {
|
||||
convert(bottomSlot);
|
||||
bottomOrd = ords[bottomSlot];
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void setBottom(final int bottom) {
|
||||
bottomSlot = bottom;
|
||||
if (readerGen[bottom] != currentReaderGen) {
|
||||
convert(bottomSlot);
|
||||
}
|
||||
bottomOrd = ords[bottom];
|
||||
assert bottomOrd >= 0;
|
||||
assert bottomOrd < lookup.length;
|
||||
bottomValue = values[bottom];
|
||||
}
|
||||
|
||||
@Override public Comparable value(int slot) {
|
||||
return values[slot];
|
||||
}
|
||||
|
||||
public String[] getValues() {
|
||||
return values;
|
||||
}
|
||||
|
||||
public int getBottomSlot() {
|
||||
return bottomSlot;
|
||||
}
|
||||
|
||||
public String getField() {
|
||||
return field;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search 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.field.data.strings;
|
||||
|
||||
import org.apache.lucene.index.IndexReader;
|
||||
import org.apache.lucene.search.FieldComparator;
|
||||
import org.elasticsearch.index.cache.field.data.FieldDataCache;
|
||||
import org.elasticsearch.index.field.data.FieldData;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
public class StringValFieldDataComparator extends FieldComparator {
|
||||
|
||||
private final String fieldName;
|
||||
|
||||
protected final FieldDataCache fieldDataCache;
|
||||
|
||||
protected FieldData currentFieldData;
|
||||
|
||||
private String[] values;
|
||||
|
||||
private String bottom;
|
||||
|
||||
public StringValFieldDataComparator(int numHits, String fieldName, FieldDataCache fieldDataCache) {
|
||||
this.fieldName = fieldName;
|
||||
this.fieldDataCache = fieldDataCache;
|
||||
values = new String[numHits];
|
||||
}
|
||||
|
||||
@Override public int compare(int slot1, int slot2) {
|
||||
final String val1 = values[slot1];
|
||||
final String val2 = values[slot2];
|
||||
if (val1 == null) {
|
||||
if (val2 == null) {
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
} else if (val2 == null) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return val1.compareTo(val2);
|
||||
}
|
||||
|
||||
@Override public int compareBottom(int doc) {
|
||||
final String val2 = currentFieldData.stringValue(doc);
|
||||
if (bottom == null) {
|
||||
if (val2 == null) {
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
} else if (val2 == null) {
|
||||
return 1;
|
||||
}
|
||||
return bottom.compareTo(val2);
|
||||
}
|
||||
|
||||
@Override public void copy(int slot, int doc) {
|
||||
values[slot] = currentFieldData.stringValue(doc);
|
||||
}
|
||||
|
||||
@Override public void setNextReader(IndexReader reader, int docBase) throws IOException {
|
||||
currentFieldData = fieldDataCache.cache(FieldData.Type.STRING, reader, fieldName);
|
||||
}
|
||||
|
||||
@Override public void setBottom(final int bottom) {
|
||||
this.bottom = values[bottom];
|
||||
}
|
||||
|
||||
@Override public Comparable value(int slot) {
|
||||
return values[slot];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search 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.field.data.support;
|
||||
|
||||
import org.apache.lucene.index.IndexReader;
|
||||
import org.apache.lucene.search.FieldComparator;
|
||||
import org.elasticsearch.index.cache.field.data.FieldDataCache;
|
||||
import org.elasticsearch.index.field.data.FieldData;
|
||||
import org.elasticsearch.index.field.data.NumericFieldData;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
public abstract class NumericFieldDataComparator extends FieldComparator {
|
||||
|
||||
private final String fieldName;
|
||||
|
||||
protected final FieldDataCache fieldDataCache;
|
||||
|
||||
protected NumericFieldData currentFieldData;
|
||||
|
||||
public NumericFieldDataComparator(String fieldName, FieldDataCache fieldDataCache) {
|
||||
this.fieldName = fieldName;
|
||||
this.fieldDataCache = fieldDataCache;
|
||||
}
|
||||
|
||||
public abstract FieldData.Type fieldDataType();
|
||||
|
||||
@Override public void setNextReader(IndexReader reader, int docBase) throws IOException {
|
||||
currentFieldData = (NumericFieldData) fieldDataCache.cache(fieldDataType(), reader, fieldName);
|
||||
}
|
||||
}
|
|
@ -167,7 +167,5 @@ public interface FieldMapper<T> {
|
|||
*/
|
||||
Filter rangeFilter(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper);
|
||||
|
||||
int sortType();
|
||||
|
||||
FieldData.Type fieldDataType();
|
||||
}
|
||||
|
|
|
@ -21,7 +21,10 @@ package org.elasticsearch.index.mapper.xcontent;
|
|||
|
||||
import org.apache.lucene.document.Field;
|
||||
import org.apache.lucene.document.Fieldable;
|
||||
import org.apache.lucene.search.*;
|
||||
import org.apache.lucene.search.Filter;
|
||||
import org.apache.lucene.search.NumericRangeFilter;
|
||||
import org.apache.lucene.search.NumericRangeQuery;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.apache.lucene.util.NumericUtils;
|
||||
import org.elasticsearch.common.Numbers;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
|
@ -169,10 +172,6 @@ public class XContentBoostFieldMapper extends XContentNumberFieldMapper<Float> i
|
|||
return value;
|
||||
}
|
||||
|
||||
@Override public int sortType() {
|
||||
return SortField.FLOAT;
|
||||
}
|
||||
|
||||
@Override public FieldData.Type fieldDataType() {
|
||||
return FieldData.Type.FLOAT;
|
||||
}
|
||||
|
|
|
@ -21,7 +21,10 @@ package org.elasticsearch.index.mapper.xcontent;
|
|||
|
||||
import org.apache.lucene.document.Field;
|
||||
import org.apache.lucene.document.Fieldable;
|
||||
import org.apache.lucene.search.*;
|
||||
import org.apache.lucene.search.Filter;
|
||||
import org.apache.lucene.search.NumericRangeFilter;
|
||||
import org.apache.lucene.search.NumericRangeQuery;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.apache.lucene.util.NumericUtils;
|
||||
import org.elasticsearch.common.Numbers;
|
||||
import org.elasticsearch.common.Strings;
|
||||
|
@ -202,10 +205,6 @@ public class XContentDateFieldMapper extends XContentNumberFieldMapper<Long> {
|
|||
return field;
|
||||
}
|
||||
|
||||
@Override public int sortType() {
|
||||
return SortField.LONG;
|
||||
}
|
||||
|
||||
@Override public FieldData.Type fieldDataType() {
|
||||
return FieldData.Type.LONG;
|
||||
}
|
||||
|
|
|
@ -21,7 +21,10 @@ package org.elasticsearch.index.mapper.xcontent;
|
|||
|
||||
import org.apache.lucene.document.Field;
|
||||
import org.apache.lucene.document.Fieldable;
|
||||
import org.apache.lucene.search.*;
|
||||
import org.apache.lucene.search.Filter;
|
||||
import org.apache.lucene.search.NumericRangeFilter;
|
||||
import org.apache.lucene.search.NumericRangeQuery;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.apache.lucene.util.NumericUtils;
|
||||
import org.elasticsearch.common.Numbers;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
|
@ -184,10 +187,6 @@ public class XContentDoubleFieldMapper extends XContentNumberFieldMapper<Double>
|
|||
return field;
|
||||
}
|
||||
|
||||
@Override public int sortType() {
|
||||
return SortField.DOUBLE;
|
||||
}
|
||||
|
||||
@Override public FieldData.Type fieldDataType() {
|
||||
return FieldData.Type.DOUBLE;
|
||||
}
|
||||
|
|
|
@ -344,10 +344,6 @@ public abstract class XContentFieldMapper<T> implements FieldMapper<T>, XContent
|
|||
mergeContext.addConflict("Mapper [" + names.fullName() + "] exists, can't merge");
|
||||
}
|
||||
|
||||
@Override public int sortType() {
|
||||
return SortField.STRING;
|
||||
}
|
||||
|
||||
@Override public FieldData.Type fieldDataType() {
|
||||
return FieldData.Type.STRING;
|
||||
}
|
||||
|
|
|
@ -21,7 +21,10 @@ package org.elasticsearch.index.mapper.xcontent;
|
|||
|
||||
import org.apache.lucene.document.Field;
|
||||
import org.apache.lucene.document.Fieldable;
|
||||
import org.apache.lucene.search.*;
|
||||
import org.apache.lucene.search.Filter;
|
||||
import org.apache.lucene.search.NumericRangeFilter;
|
||||
import org.apache.lucene.search.NumericRangeQuery;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.apache.lucene.util.NumericUtils;
|
||||
import org.elasticsearch.common.Numbers;
|
||||
import org.elasticsearch.common.Strings;
|
||||
|
@ -183,10 +186,6 @@ public class XContentFloatFieldMapper extends XContentNumberFieldMapper<Float> {
|
|||
return field;
|
||||
}
|
||||
|
||||
@Override public int sortType() {
|
||||
return SortField.FLOAT;
|
||||
}
|
||||
|
||||
@Override public FieldData.Type fieldDataType() {
|
||||
return FieldData.Type.FLOAT;
|
||||
}
|
||||
|
|
|
@ -21,7 +21,10 @@ package org.elasticsearch.index.mapper.xcontent;
|
|||
|
||||
import org.apache.lucene.document.Field;
|
||||
import org.apache.lucene.document.Fieldable;
|
||||
import org.apache.lucene.search.*;
|
||||
import org.apache.lucene.search.Filter;
|
||||
import org.apache.lucene.search.NumericRangeFilter;
|
||||
import org.apache.lucene.search.NumericRangeQuery;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.apache.lucene.util.NumericUtils;
|
||||
import org.elasticsearch.common.Numbers;
|
||||
import org.elasticsearch.common.Strings;
|
||||
|
@ -183,10 +186,6 @@ public class XContentIntegerFieldMapper extends XContentNumberFieldMapper<Intege
|
|||
return field;
|
||||
}
|
||||
|
||||
@Override public int sortType() {
|
||||
return SortField.INT;
|
||||
}
|
||||
|
||||
@Override public FieldData.Type fieldDataType() {
|
||||
return FieldData.Type.INT;
|
||||
}
|
||||
|
|
|
@ -21,7 +21,10 @@ package org.elasticsearch.index.mapper.xcontent;
|
|||
|
||||
import org.apache.lucene.document.Field;
|
||||
import org.apache.lucene.document.Fieldable;
|
||||
import org.apache.lucene.search.*;
|
||||
import org.apache.lucene.search.Filter;
|
||||
import org.apache.lucene.search.NumericRangeFilter;
|
||||
import org.apache.lucene.search.NumericRangeQuery;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.apache.lucene.util.NumericUtils;
|
||||
import org.elasticsearch.common.Numbers;
|
||||
import org.elasticsearch.common.Strings;
|
||||
|
@ -183,10 +186,6 @@ public class XContentLongFieldMapper extends XContentNumberFieldMapper<Long> {
|
|||
return field;
|
||||
}
|
||||
|
||||
@Override public int sortType() {
|
||||
return SortField.LONG;
|
||||
}
|
||||
|
||||
@Override public FieldData.Type fieldDataType() {
|
||||
return FieldData.Type.LONG;
|
||||
}
|
||||
|
|
|
@ -161,8 +161,6 @@ public abstract class XContentNumberFieldMapper<T extends Number> extends XConte
|
|||
builder.field("precision_step", precisionStep);
|
||||
}
|
||||
|
||||
@Override public abstract int sortType();
|
||||
|
||||
@Override public abstract FieldData.Type fieldDataType();
|
||||
|
||||
/**
|
||||
|
|
|
@ -21,7 +21,10 @@ package org.elasticsearch.index.mapper.xcontent;
|
|||
|
||||
import org.apache.lucene.document.Field;
|
||||
import org.apache.lucene.document.Fieldable;
|
||||
import org.apache.lucene.search.*;
|
||||
import org.apache.lucene.search.Filter;
|
||||
import org.apache.lucene.search.NumericRangeFilter;
|
||||
import org.apache.lucene.search.NumericRangeQuery;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.apache.lucene.util.NumericUtils;
|
||||
import org.elasticsearch.common.Numbers;
|
||||
import org.elasticsearch.common.Strings;
|
||||
|
@ -183,10 +186,6 @@ public class XContentShortFieldMapper extends XContentNumberFieldMapper<Short> {
|
|||
return field;
|
||||
}
|
||||
|
||||
@Override public int sortType() {
|
||||
return SortField.SHORT;
|
||||
}
|
||||
|
||||
@Override public FieldData.Type fieldDataType() {
|
||||
return FieldData.Type.SHORT;
|
||||
}
|
||||
|
|
|
@ -156,17 +156,7 @@ public class SearchSourceBuilder implements ToXContent {
|
|||
reverse = true;
|
||||
}
|
||||
}
|
||||
return sort(name, null, reverse);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a sort against the given field name and if it should be revered or not.
|
||||
*
|
||||
* @param name The name of the field to sort by
|
||||
* @param reverse Should be soring be reversed or not
|
||||
*/
|
||||
public SearchSourceBuilder sort(String name, boolean reverse) {
|
||||
return sort(name, null, reverse);
|
||||
return sort(name, reverse);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -175,31 +165,20 @@ public class SearchSourceBuilder implements ToXContent {
|
|||
* @param name The name of the field to sort by
|
||||
*/
|
||||
public SearchSourceBuilder sort(String name) {
|
||||
return sort(name, null, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a sort against the given field name of the given type.
|
||||
*
|
||||
* @param name The name of the field to sort by
|
||||
* @param type The type of sort to perform
|
||||
*/
|
||||
public SearchSourceBuilder sort(String name, String type) {
|
||||
return sort(name, type, false);
|
||||
return sort(name, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a sort against the given field name and if it should be revered or not.
|
||||
*
|
||||
* @param name The name of the field to sort by
|
||||
* @param type The type of the sort to perform
|
||||
* @param reverse Should the sort be reversed or not
|
||||
*/
|
||||
public SearchSourceBuilder sort(String name, String type, boolean reverse) {
|
||||
public SearchSourceBuilder sort(String name, boolean reverse) {
|
||||
if (sortFields == null) {
|
||||
sortFields = newArrayListWithCapacity(2);
|
||||
}
|
||||
sortFields.add(new SortTuple(name, reverse, type));
|
||||
sortFields.add(new SortTuple(name, reverse));
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -366,12 +345,9 @@ public class SearchSourceBuilder implements ToXContent {
|
|||
for (SortTuple sortTuple : sortFields) {
|
||||
builder.field(sortTuple.fieldName());
|
||||
builder.startObject();
|
||||
if (sortTuple.reverse) {
|
||||
if (sortTuple.reverse()) {
|
||||
builder.field("reverse", true);
|
||||
}
|
||||
if (sortTuple.type != null) {
|
||||
builder.field("type", sortTuple.type());
|
||||
}
|
||||
builder.endObject();
|
||||
}
|
||||
builder.endObject();
|
||||
|
@ -429,12 +405,10 @@ public class SearchSourceBuilder implements ToXContent {
|
|||
private static class SortTuple {
|
||||
private final String fieldName;
|
||||
private final boolean reverse;
|
||||
private final String type;
|
||||
|
||||
private SortTuple(String fieldName, boolean reverse, String type) {
|
||||
private SortTuple(String fieldName, boolean reverse) {
|
||||
this.fieldName = fieldName;
|
||||
this.reverse = reverse;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String fieldName() {
|
||||
|
@ -444,9 +418,5 @@ public class SearchSourceBuilder implements ToXContent {
|
|||
public boolean reverse() {
|
||||
return reverse;
|
||||
}
|
||||
|
||||
public String type() {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -99,7 +99,22 @@ public class QueryPhase implements SearchPhase {
|
|||
// if 0 was asked, change it to 1 since 0 is not allowed
|
||||
numDocs = 1;
|
||||
}
|
||||
boolean sort = false;
|
||||
// try and optimize for a case where the sorting is based on score, this is how we work by default!
|
||||
if (searchContext.sort() != null) {
|
||||
if (searchContext.sort().getSort().length > 0) {
|
||||
sort = true;
|
||||
} else {
|
||||
SortField sortField = searchContext.sort().getSort()[0];
|
||||
if (sortField.getType() == SortField.SCORE && !sortField.getReverse()) {
|
||||
sort = false;
|
||||
} else {
|
||||
sort = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sort) {
|
||||
topDocs = searchContext.searcher().search(query, null, numDocs, searchContext.sort());
|
||||
} else {
|
||||
topDocs = searchContext.searcher().search(query, numDocs);
|
||||
|
|
|
@ -21,12 +21,9 @@ package org.elasticsearch.search.query;
|
|||
|
||||
import org.apache.lucene.search.Sort;
|
||||
import org.apache.lucene.search.SortField;
|
||||
import org.elasticsearch.common.Booleans;
|
||||
import org.elasticsearch.common.collect.Lists;
|
||||
import org.elasticsearch.common.trove.ExtTObjectIntHasMap;
|
||||
import org.elasticsearch.common.trove.TObjectIntHashMap;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.index.mapper.FieldMappers;
|
||||
import org.elasticsearch.index.mapper.FieldMapper;
|
||||
import org.elasticsearch.search.SearchParseElement;
|
||||
import org.elasticsearch.search.SearchParseException;
|
||||
import org.elasticsearch.search.internal.SearchContext;
|
||||
|
@ -39,22 +36,12 @@ import java.util.List;
|
|||
*/
|
||||
public class SortParseElement implements SearchParseElement {
|
||||
|
||||
private final TObjectIntHashMap<String> sortFieldTypesMapper = new ExtTObjectIntHasMap<String>().defaultReturnValue(-1);
|
||||
|
||||
private static final SortField SORT_SCORE = new SortField(null, SortField.SCORE);
|
||||
private static final SortField SORT_SCORE_REVERSE = new SortField(null, SortField.SCORE, true);
|
||||
private static final SortField SORT_DOC = new SortField(null, SortField.DOC);
|
||||
private static final SortField SORT_DOC_REVERSE = new SortField(null, SortField.DOC, true);
|
||||
|
||||
public SortParseElement() {
|
||||
sortFieldTypesMapper.put("string", SortField.STRING);
|
||||
sortFieldTypesMapper.put("int", SortField.INT);
|
||||
sortFieldTypesMapper.put("float", SortField.FLOAT);
|
||||
sortFieldTypesMapper.put("long", SortField.LONG);
|
||||
sortFieldTypesMapper.put("double", SortField.DOUBLE);
|
||||
sortFieldTypesMapper.put("short", SortField.SHORT);
|
||||
sortFieldTypesMapper.put("byte", SortField.BYTE);
|
||||
sortFieldTypesMapper.put("string_val", SortField.STRING_VAL);
|
||||
}
|
||||
|
||||
@Override public void parse(XContentParser parser, SearchContext context) throws Exception {
|
||||
|
@ -65,7 +52,7 @@ public class SortParseElement implements SearchParseElement {
|
|||
if (token == XContentParser.Token.START_OBJECT) {
|
||||
addCompoundSortField(parser, context, sortFields);
|
||||
} else if (token == XContentParser.Token.VALUE_STRING) {
|
||||
addSortField(context, sortFields, parser.text(), false, -1);
|
||||
addSortField(context, sortFields, parser.text(), false);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -83,36 +70,18 @@ public class SortParseElement implements SearchParseElement {
|
|||
String fieldName = parser.currentName();
|
||||
boolean reverse = false;
|
||||
String innerJsonName = null;
|
||||
int type = -1;
|
||||
token = parser.nextToken();
|
||||
if (token == XContentParser.Token.VALUE_STRING) {
|
||||
String direction = parser.text();
|
||||
if (direction.equals("asc")) {
|
||||
if ("score".equals(fieldName)) {
|
||||
reverse = true;
|
||||
} else {
|
||||
reverse = false;
|
||||
}
|
||||
reverse = "score".equals(fieldName);
|
||||
} else if (direction.equals("desc")) {
|
||||
if ("score".equals(fieldName)) {
|
||||
reverse = false;
|
||||
} else {
|
||||
reverse = true;
|
||||
}
|
||||
reverse = !"score".equals(fieldName);
|
||||
}
|
||||
} else {
|
||||
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
||||
if (token == XContentParser.Token.FIELD_NAME) {
|
||||
innerJsonName = parser.currentName();
|
||||
} else if (token == XContentParser.Token.VALUE_STRING) {
|
||||
if ("type".equals(innerJsonName)) {
|
||||
type = sortFieldTypesMapper.get(parser.text());
|
||||
if (type == -1) {
|
||||
throw new SearchParseException(context, "No sort type for [" + parser.text() + "] with field [" + fieldName + "]");
|
||||
}
|
||||
} else if ("reverse".equals(innerJsonName)) {
|
||||
reverse = Booleans.parseBoolean(parser.text(), reverse);
|
||||
}
|
||||
} else if (token.isValue()) {
|
||||
if ("reverse".equals(innerJsonName)) {
|
||||
reverse = parser.booleanValue();
|
||||
|
@ -120,12 +89,12 @@ public class SortParseElement implements SearchParseElement {
|
|||
}
|
||||
}
|
||||
}
|
||||
addSortField(context, sortFields, fieldName, reverse, type);
|
||||
addSortField(context, sortFields, fieldName, reverse);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addSortField(SearchContext context, List<SortField> sortFields, String fieldName, boolean reverse, int type) {
|
||||
private void addSortField(SearchContext context, List<SortField> sortFields, String fieldName, boolean reverse) {
|
||||
if ("score".equals(fieldName)) {
|
||||
if (reverse) {
|
||||
sortFields.add(SORT_SCORE_REVERSE);
|
||||
|
@ -139,18 +108,11 @@ public class SortParseElement implements SearchParseElement {
|
|||
sortFields.add(SORT_DOC);
|
||||
}
|
||||
} else {
|
||||
FieldMappers fieldMappers = context.mapperService().smartNameFieldMappers(fieldName);
|
||||
if (fieldMappers == null || fieldMappers.mappers().isEmpty()) {
|
||||
if (type == -1) {
|
||||
throw new SearchParseException(context, "No built in mapping found for [" + fieldName + "], and no explicit type defined");
|
||||
}
|
||||
} else {
|
||||
fieldName = fieldMappers.mappers().get(0).names().indexName();
|
||||
if (type == -1) {
|
||||
type = fieldMappers.mappers().get(0).sortType();
|
||||
}
|
||||
FieldMapper fieldMapper = context.mapperService().smartNameFieldMapper(fieldName);
|
||||
if (fieldMapper == null) {
|
||||
throw new SearchParseException(context, "No mapping found for [" + fieldName + "]");
|
||||
}
|
||||
sortFields.add(new SortField(fieldName, type, reverse));
|
||||
sortFields.add(new SortField(fieldName, fieldMapper.fieldDataType().newFieldComparatorSource(context.fieldDataCache()), reverse));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -67,7 +67,7 @@ import static org.hamcrest.MatcherAssert.*;
|
|||
import static org.hamcrest.Matchers.*;
|
||||
|
||||
/**
|
||||
* @author kimchy (Shay Banon)
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
public class TwoInstanceEmbeddedSearchTests extends AbstractNodesTests {
|
||||
|
||||
|
|
Loading…
Reference in New Issue