Scripts: Return new lists on calls to getValues.
Scripts currently share the same list across invocations to getValues. This caused a bug in script fields where all documents coming from the same segment would get the same values (basically, for the next document for which script values have been requested). Scripts now return a fresh new list on every invocation to `getValues`. Close #8576
This commit is contained in:
parent
0f4ca09e54
commit
d22645cbfc
|
@ -1,163 +0,0 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch 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.common.util;
|
||||
|
||||
import java.util.AbstractList;
|
||||
import java.util.RandomAccess;
|
||||
|
||||
import org.apache.lucene.util.ArrayUtil;
|
||||
|
||||
import com.google.common.primitives.Doubles;
|
||||
|
||||
public final class SlicedDoubleList extends AbstractList<Double> implements RandomAccess {
|
||||
|
||||
public static final SlicedDoubleList EMPTY = new SlicedDoubleList(0);
|
||||
|
||||
public double[] values;
|
||||
public int offset;
|
||||
public int length;
|
||||
|
||||
public SlicedDoubleList(int capacity) {
|
||||
this(new double[capacity], 0, capacity);
|
||||
}
|
||||
|
||||
public SlicedDoubleList(double[] values, int offset, int length) {
|
||||
this.values = values;
|
||||
this.offset = offset;
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return size() == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double get(int index) {
|
||||
assert index < size();
|
||||
return values[offset + index];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Object target) {
|
||||
// Overridden to prevent a ton of boxing
|
||||
return (target instanceof Double)
|
||||
&& indexOf(values, (Double) target, offset, offset+length) != -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int indexOf(Object target) {
|
||||
// Overridden to prevent a ton of boxing
|
||||
if (target instanceof Double) {
|
||||
int i = indexOf(values, (Double) target, offset, offset+length);
|
||||
if (i >= 0) {
|
||||
return i - offset;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int lastIndexOf(Object target) {
|
||||
// Overridden to prevent a ton of boxing
|
||||
if (target instanceof Double) {
|
||||
int i = lastIndexOf(values, (Double) target, offset, offset+length);
|
||||
if (i >= 0) {
|
||||
return i - offset;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double set(int index, Double element) {
|
||||
throw new UnsupportedOperationException("modifying list opertations are not implemented");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
if (object == this) {
|
||||
return true;
|
||||
}
|
||||
if (object instanceof SlicedDoubleList) {
|
||||
SlicedDoubleList that = (SlicedDoubleList) object;
|
||||
int size = size();
|
||||
if (that.size() != size) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (values[offset + i] != that.values[that.offset + i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return super.equals(object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = 1;
|
||||
for (int i = 0; i < length; i++) {
|
||||
result = 31 * result + Doubles.hashCode(values[offset+i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder(size() * 10);
|
||||
builder.append('[');
|
||||
if (length > 0) {
|
||||
builder.append(values[offset]);
|
||||
for (int i = 1; i < length; i++) {
|
||||
builder.append(", ").append(values[offset+i]);
|
||||
}
|
||||
}
|
||||
return builder.append(']').toString();
|
||||
}
|
||||
|
||||
private static int indexOf(double[] array, double target, int start, int end) {
|
||||
for (int i = start; i < end; i++) {
|
||||
if (array[i] == target) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private static int lastIndexOf(double[] array, double target, int start, int end) {
|
||||
for (int i = end - 1; i >= start; i--) {
|
||||
if (array[i] == target) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public void grow(int newLength) {
|
||||
assert offset == 0;
|
||||
values = ArrayUtil.grow(values, newLength);
|
||||
}
|
||||
}
|
|
@ -1,164 +0,0 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch 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.common.util;
|
||||
|
||||
import java.util.AbstractList;
|
||||
import java.util.RandomAccess;
|
||||
|
||||
import org.apache.lucene.util.ArrayUtil;
|
||||
import org.apache.lucene.util.LongsRef;
|
||||
|
||||
import com.google.common.primitives.Longs;
|
||||
|
||||
public final class SlicedLongList extends AbstractList<Long> implements RandomAccess {
|
||||
|
||||
public static final SlicedLongList EMPTY = new SlicedLongList(LongsRef.EMPTY_LONGS, 0, 0);
|
||||
|
||||
public long[] values;
|
||||
public int offset;
|
||||
public int length;
|
||||
|
||||
public SlicedLongList(int capacity) {
|
||||
this(new long[capacity], 0, capacity);
|
||||
}
|
||||
|
||||
public SlicedLongList(long[] values, int offset, int length) {
|
||||
this.values = values;
|
||||
this.offset = offset;
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return size() == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long get(int index) {
|
||||
assert index < size();
|
||||
return values[offset + index];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Object target) {
|
||||
// Overridden to prevent a ton of boxing
|
||||
return (target instanceof Long)
|
||||
&& indexOf(values, (Long) target, offset, offset+length) != -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int indexOf(Object target) {
|
||||
// Overridden to prevent a ton of boxing
|
||||
if (target instanceof Long) {
|
||||
int i = indexOf(values, (Long) target, offset, offset+length);
|
||||
if (i >= 0) {
|
||||
return i - offset;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int lastIndexOf(Object target) {
|
||||
// Overridden to prevent a ton of boxing
|
||||
if (target instanceof Long) {
|
||||
int i = lastIndexOf(values, (Long) target, offset, offset+length);
|
||||
if (i >= 0) {
|
||||
return i - offset;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long set(int index, Long element) {
|
||||
throw new UnsupportedOperationException("modifying list opertations are not implemented");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
if (object == this) {
|
||||
return true;
|
||||
}
|
||||
if (object instanceof SlicedLongList) {
|
||||
SlicedLongList that = (SlicedLongList) object;
|
||||
int size = size();
|
||||
if (that.size() != size) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (values[offset + i] != that.values[that.offset + i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return super.equals(object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = 1;
|
||||
for (int i = 0; i < length; i++) {
|
||||
result = 31 * result + Longs.hashCode(values[offset+i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder(size() * 10);
|
||||
builder.append('[');
|
||||
if (length > 0) {
|
||||
builder.append(values[offset]);
|
||||
for (int i = 1; i < length; i++) {
|
||||
builder.append(", ").append(values[offset+i]);
|
||||
}
|
||||
}
|
||||
return builder.append(']').toString();
|
||||
}
|
||||
|
||||
private static int indexOf(long[] array, long target, int start, int end) {
|
||||
for (int i = start; i < end; i++) {
|
||||
if (array[i] == target) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private static int lastIndexOf(long[] array, long target, int start, int end) {
|
||||
for (int i = end - 1; i >= start; i--) {
|
||||
if (array[i] == target) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public void grow(int newLength) {
|
||||
assert offset == 0;
|
||||
values = ArrayUtil.grow(values, newLength);
|
||||
}
|
||||
}
|
|
@ -1,106 +0,0 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch 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.common.util;
|
||||
|
||||
import java.util.AbstractList;
|
||||
import java.util.RandomAccess;
|
||||
|
||||
// TODO this could use some javadocs
|
||||
public abstract class SlicedObjectList<T> extends AbstractList<T> implements RandomAccess {
|
||||
|
||||
public T[] values;
|
||||
public int offset;
|
||||
public int length;
|
||||
|
||||
public SlicedObjectList(T[] values) {
|
||||
this(values, 0, values.length);
|
||||
}
|
||||
|
||||
public SlicedObjectList(T[] values, int offset, int length) {
|
||||
this.values = values;
|
||||
this.offset = offset;
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return size() == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T get(int index) {
|
||||
assert index < size();
|
||||
return values[offset + index];
|
||||
}
|
||||
|
||||
@Override
|
||||
public T set(int index, T element) {
|
||||
throw new UnsupportedOperationException("modifying list opertations are not implemented");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
if (object == this) {
|
||||
return true;
|
||||
}
|
||||
if (object instanceof SlicedObjectList) {
|
||||
SlicedObjectList<?> that = (SlicedObjectList<?>) object;
|
||||
int size = size();
|
||||
if (that.size() != size) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (values[offset + i].equals(that.values[that.offset + i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return super.equals(object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = 1;
|
||||
for (int i = 0; i < length; i++) {
|
||||
result = 31 * result + values[offset+i].hashCode();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder(size() * 10);
|
||||
builder.append('[');
|
||||
if (length > 0) {
|
||||
builder.append(values[offset]);
|
||||
for (int i = 1; i < length; i++) {
|
||||
builder.append(", ").append(values[offset+i]);
|
||||
}
|
||||
}
|
||||
return builder.append(']').toString();
|
||||
}
|
||||
|
||||
public abstract void grow(int newLength);
|
||||
}
|
|
@ -19,64 +19,47 @@
|
|||
|
||||
package org.elasticsearch.index.fielddata;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import org.apache.lucene.index.SortedNumericDocValues;
|
||||
import org.apache.lucene.util.ArrayUtil;
|
||||
import org.apache.lucene.util.BytesRef;
|
||||
import org.apache.lucene.util.RamUsageEstimator;
|
||||
import org.elasticsearch.common.geo.GeoDistance;
|
||||
import org.elasticsearch.common.geo.GeoPoint;
|
||||
import org.elasticsearch.common.unit.DistanceUnit;
|
||||
import org.elasticsearch.common.util.SlicedDoubleList;
|
||||
import org.elasticsearch.common.util.SlicedLongList;
|
||||
import org.elasticsearch.common.util.SlicedObjectList;
|
||||
import org.joda.time.DateTimeZone;
|
||||
import org.joda.time.MutableDateTime;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.AbstractList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* Script level doc values, the assumption is that any implementation will implement a <code>getValue</code>
|
||||
* and a <code>getValues</code> that return the relevant type that then can be used in scripts.
|
||||
*/
|
||||
public abstract class ScriptDocValues {
|
||||
public interface ScriptDocValues<T> extends List<T> {
|
||||
|
||||
protected int docId;
|
||||
protected boolean listLoaded = false;
|
||||
/**
|
||||
* Set the current doc ID.
|
||||
*/
|
||||
void setNextDocId(int docId);
|
||||
|
||||
public void setNextDocId(int docId) {
|
||||
this.docId = docId;
|
||||
this.listLoaded = false;
|
||||
}
|
||||
/**
|
||||
* Return a copy of the list of the values for the current document.
|
||||
*/
|
||||
List<T> getValues();
|
||||
|
||||
public abstract boolean isEmpty();
|
||||
|
||||
public abstract List<?> getValues();
|
||||
|
||||
public final static class Strings extends ScriptDocValues {
|
||||
public final static class Strings extends AbstractList<String> implements ScriptDocValues<String> {
|
||||
|
||||
private final SortedBinaryDocValues values;
|
||||
private SlicedObjectList<String> list;
|
||||
|
||||
public Strings(SortedBinaryDocValues values) {
|
||||
this.values = values;
|
||||
list = new SlicedObjectList<String>(new String[0]) {
|
||||
|
||||
@Override
|
||||
public void grow(int newLength) {
|
||||
assert offset == 0; // NOTE: senseless if offset != 0
|
||||
if (values.length >= newLength) {
|
||||
return;
|
||||
}
|
||||
values = Arrays.copyOf(values, ArrayUtil.oversize(newLength, RamUsageEstimator.NUM_BYTES_OBJECT_REF));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
public void setNextDocId(int docId) {
|
||||
values.setDocument(docId);
|
||||
return values.count() == 0;
|
||||
}
|
||||
|
||||
public SortedBinaryDocValues getInternalValues() {
|
||||
|
@ -84,7 +67,6 @@ public abstract class ScriptDocValues {
|
|||
}
|
||||
|
||||
public BytesRef getBytesValue() {
|
||||
values.setDocument(docId);
|
||||
if (values.count() > 0) {
|
||||
return values.valueAt(0);
|
||||
} else {
|
||||
|
@ -101,46 +83,42 @@ public abstract class ScriptDocValues {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getValues() {
|
||||
if (!listLoaded) {
|
||||
values.setDocument(docId);
|
||||
final int numValues = values.count();
|
||||
list.offset = 0;
|
||||
list.grow(numValues);
|
||||
list.length = numValues;
|
||||
for (int i = 0; i < numValues; i++) {
|
||||
list.values[i] = values.valueAt(i).utf8ToString();
|
||||
return ImmutableList.copyOf(this);
|
||||
}
|
||||
listLoaded = true;
|
||||
|
||||
@Override
|
||||
public String get(int index) {
|
||||
return values.valueAt(index).utf8ToString();
|
||||
}
|
||||
return list;
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return values.count();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class Longs extends ScriptDocValues {
|
||||
public static class Longs extends AbstractList<Long> implements ScriptDocValues<Long> {
|
||||
|
||||
private final SortedNumericDocValues values;
|
||||
private final MutableDateTime date = new MutableDateTime(0, DateTimeZone.UTC);
|
||||
private final SlicedLongList list;
|
||||
|
||||
public Longs(SortedNumericDocValues values) {
|
||||
this.values = values;
|
||||
this.list = new SlicedLongList(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNextDocId(int docId) {
|
||||
values.setDocument(docId);
|
||||
}
|
||||
|
||||
public SortedNumericDocValues getInternalValues() {
|
||||
return this.values;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
values.setDocument(docId);
|
||||
return values.count() == 0;
|
||||
}
|
||||
|
||||
public long getValue() {
|
||||
values.setDocument(docId);
|
||||
int numValues = values.count();
|
||||
if (numValues == 0) {
|
||||
return 0l;
|
||||
|
@ -148,19 +126,9 @@ public abstract class ScriptDocValues {
|
|||
return values.valueAt(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Long> getValues() {
|
||||
if (!listLoaded) {
|
||||
values.setDocument(docId);
|
||||
final int numValues = values.count();
|
||||
list.offset = 0;
|
||||
list.grow(numValues);
|
||||
list.length = numValues;
|
||||
for (int i = 0; i < numValues; i++) {
|
||||
list.values[i] = values.valueAt(i);
|
||||
}
|
||||
listLoaded = true;
|
||||
}
|
||||
return list;
|
||||
return ImmutableList.copyOf(this);
|
||||
}
|
||||
|
||||
public MutableDateTime getDate() {
|
||||
|
@ -168,32 +136,36 @@ public abstract class ScriptDocValues {
|
|||
return date;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long get(int index) {
|
||||
return values.valueAt(index);
|
||||
}
|
||||
|
||||
public static class Doubles extends ScriptDocValues {
|
||||
@Override
|
||||
public int size() {
|
||||
return values.count();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class Doubles extends AbstractList<Double> implements ScriptDocValues<Double> {
|
||||
|
||||
private final SortedNumericDoubleValues values;
|
||||
private final SlicedDoubleList list;
|
||||
|
||||
public Doubles(SortedNumericDoubleValues values) {
|
||||
this.values = values;
|
||||
this.list = new SlicedDoubleList(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNextDocId(int docId) {
|
||||
values.setDocument(docId);
|
||||
}
|
||||
|
||||
public SortedNumericDoubleValues getInternalValues() {
|
||||
return this.values;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
values.setDocument(docId);
|
||||
return values.count() == 0;
|
||||
}
|
||||
|
||||
|
||||
public double getValue() {
|
||||
values.setDocument(docId);
|
||||
int numValues = values.count();
|
||||
if (numValues == 0) {
|
||||
return 0d;
|
||||
|
@ -201,50 +173,36 @@ public abstract class ScriptDocValues {
|
|||
return values.valueAt(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Double> getValues() {
|
||||
if (!listLoaded) {
|
||||
values.setDocument(docId);
|
||||
int numValues = values.count();
|
||||
list.offset = 0;
|
||||
list.grow(numValues);
|
||||
list.length = numValues;
|
||||
for (int i = 0; i < numValues; i++) {
|
||||
list.values[i] = values.valueAt(i);
|
||||
return ImmutableList.copyOf(this);
|
||||
}
|
||||
listLoaded = true;
|
||||
|
||||
@Override
|
||||
public Double get(int index) {
|
||||
return values.valueAt(index);
|
||||
}
|
||||
return list;
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return values.count();
|
||||
}
|
||||
}
|
||||
|
||||
public static class GeoPoints extends ScriptDocValues {
|
||||
public static class GeoPoints extends AbstractList<GeoPoint> implements ScriptDocValues<GeoPoint> {
|
||||
|
||||
private final MultiGeoPointValues values;
|
||||
private final SlicedObjectList<GeoPoint> list;
|
||||
|
||||
public GeoPoints(MultiGeoPointValues values) {
|
||||
this.values = values;
|
||||
list = new SlicedObjectList<GeoPoint>(new GeoPoint[0]) {
|
||||
|
||||
@Override
|
||||
public void grow(int newLength) {
|
||||
assert offset == 0; // NOTE: senseless if offset != 0
|
||||
if (values.length >= newLength) {
|
||||
return;
|
||||
}
|
||||
values = Arrays.copyOf(values, ArrayUtil.oversize(newLength, RamUsageEstimator.NUM_BYTES_OBJECT_REF));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
public void setNextDocId(int docId) {
|
||||
values.setDocument(docId);
|
||||
return values.count() == 0;
|
||||
}
|
||||
|
||||
public GeoPoint getValue() {
|
||||
values.setDocument(docId);
|
||||
int numValues = values.count();
|
||||
if (numValues == 0) {
|
||||
return null;
|
||||
|
@ -279,25 +237,18 @@ public abstract class ScriptDocValues {
|
|||
}
|
||||
|
||||
public List<GeoPoint> getValues() {
|
||||
if (!listLoaded) {
|
||||
values.setDocument(docId);
|
||||
int numValues = values.count();
|
||||
list.offset = 0;
|
||||
list.grow(numValues);
|
||||
list.length = numValues;
|
||||
for (int i = 0; i < numValues; i++) {
|
||||
GeoPoint next = values.valueAt(i);
|
||||
GeoPoint point = list.values[i];
|
||||
if (point == null) {
|
||||
point = list.values[i] = new GeoPoint();
|
||||
return ImmutableList.copyOf(this);
|
||||
}
|
||||
point.reset(next.lat(), next.lon());
|
||||
list.values[i] = point;
|
||||
}
|
||||
listLoaded = true;
|
||||
}
|
||||
return list;
|
||||
|
||||
@Override
|
||||
public GeoPoint get(int index) {
|
||||
final GeoPoint point = values.valueAt(index);
|
||||
return new GeoPoint(point.lat(), point.lon());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return values.count();
|
||||
}
|
||||
|
||||
public double factorDistance(double lat, double lon) {
|
||||
|
|
|
@ -1,120 +0,0 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch 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.common.util;
|
||||
|
||||
import org.elasticsearch.test.ElasticsearchTestCase;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
|
||||
/**
|
||||
* Tests for {@link SlicedDoubleList}
|
||||
*/
|
||||
public class SlicedDoubleListTests extends ElasticsearchTestCase {
|
||||
|
||||
@Test
|
||||
public void testCapacity() {
|
||||
SlicedDoubleList list = new SlicedDoubleList(5);
|
||||
assertThat(list.length, equalTo(5));
|
||||
assertThat(list.offset, equalTo(0));
|
||||
assertThat(list.values.length, equalTo(5));
|
||||
assertThat(list.size(), equalTo(5));
|
||||
|
||||
|
||||
list = new SlicedDoubleList(new double[10], 5, 5);
|
||||
assertThat(list.length, equalTo(5));
|
||||
assertThat(list.offset, equalTo(5));
|
||||
assertThat(list.size(), equalTo(5));
|
||||
assertThat(list.values.length, equalTo(10));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGrow() {
|
||||
SlicedDoubleList list = new SlicedDoubleList(5);
|
||||
list.length = 1000;
|
||||
for (int i = 0; i < list.length; i++) {
|
||||
list.grow(i+1);
|
||||
list.values[i] = ((double)i);
|
||||
}
|
||||
int expected = 0;
|
||||
for (Double d : list) {
|
||||
assertThat((double)expected++, equalTo(d));
|
||||
}
|
||||
|
||||
for (int i = 0; i < list.length; i++) {
|
||||
assertThat((double)i, equalTo(list.get(i)));
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
for (int i = list.offset; i < list.offset+list.length; i++) {
|
||||
assertThat((double)count++, equalTo(list.values[i]));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIndexOf() {
|
||||
SlicedDoubleList list = new SlicedDoubleList(5);
|
||||
list.length = 1000;
|
||||
for (int i = 0; i < list.length; i++) {
|
||||
list.grow(i+1);
|
||||
list.values[i] = ((double)i%100);
|
||||
}
|
||||
|
||||
assertThat(999, equalTo(list.lastIndexOf(99.0d)));
|
||||
assertThat(99, equalTo(list.indexOf(99.0d)));
|
||||
|
||||
assertThat(-1, equalTo(list.lastIndexOf(100.0d)));
|
||||
assertThat(-1, equalTo(list.indexOf(100.0d)));
|
||||
}
|
||||
|
||||
public void testIsEmpty() {
|
||||
SlicedDoubleList list = new SlicedDoubleList(5);
|
||||
assertThat(false, equalTo(list.isEmpty()));
|
||||
list.length = 0;
|
||||
assertThat(true, equalTo(list.isEmpty()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSet() {
|
||||
SlicedDoubleList list = new SlicedDoubleList(5);
|
||||
try {
|
||||
list.set(0, (double)4);
|
||||
fail();
|
||||
} catch (UnsupportedOperationException ex) {
|
||||
}
|
||||
try {
|
||||
list.add((double)4);
|
||||
fail();
|
||||
} catch (UnsupportedOperationException ex) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToString() {
|
||||
SlicedDoubleList list = new SlicedDoubleList(5);
|
||||
assertThat("[0.0, 0.0, 0.0, 0.0, 0.0]", equalTo(list.toString()));
|
||||
for (int i = 0; i < list.length; i++) {
|
||||
list.grow(i+1);
|
||||
list.values[i] = ((double)i);
|
||||
}
|
||||
assertThat("[0.0, 1.0, 2.0, 3.0, 4.0]", equalTo(list.toString()));
|
||||
}
|
||||
|
||||
}
|
|
@ -1,119 +0,0 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch 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.common.util;
|
||||
|
||||
import org.elasticsearch.test.ElasticsearchTestCase;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
|
||||
/**
|
||||
* Tests for {@link SlicedLongList}
|
||||
*/
|
||||
public class SlicedLongListTests extends ElasticsearchTestCase {
|
||||
|
||||
@Test
|
||||
public void testCapacity() {
|
||||
SlicedLongList list = new SlicedLongList(5);
|
||||
assertThat(list.length, equalTo(5));
|
||||
assertThat(list.offset, equalTo(0));
|
||||
assertThat(list.values.length, equalTo(5));
|
||||
assertThat(list.size(), equalTo(5));
|
||||
|
||||
list = new SlicedLongList(new long[10], 5, 5);
|
||||
assertThat(list.length, equalTo(5));
|
||||
assertThat(list.offset, equalTo(5));
|
||||
assertThat(list.size(), equalTo(5));
|
||||
assertThat(list.values.length, equalTo(10));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGrow() {
|
||||
SlicedLongList list = new SlicedLongList(5);
|
||||
list.length = 1000;
|
||||
for (int i = 0; i < list.length; i++) {
|
||||
list.grow(i+1);
|
||||
list.values[i] = ((long)i);
|
||||
}
|
||||
int expected = 0;
|
||||
for (Long d : list) {
|
||||
assertThat((long)expected++, equalTo(d));
|
||||
}
|
||||
|
||||
for (int i = 0; i < list.length; i++) {
|
||||
assertThat((long)i, equalTo(list.get(i)));
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
for (int i = list.offset; i < list.offset+list.length; i++) {
|
||||
assertThat((long)count++, equalTo(list.values[i]));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSet() {
|
||||
SlicedLongList list = new SlicedLongList(5);
|
||||
try {
|
||||
list.set(0, (long)4);
|
||||
fail();
|
||||
} catch (UnsupportedOperationException ex) {
|
||||
}
|
||||
try {
|
||||
list.add((long)4);
|
||||
fail();
|
||||
} catch (UnsupportedOperationException ex) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIndexOf() {
|
||||
SlicedLongList list = new SlicedLongList(5);
|
||||
list.length = 1000;
|
||||
for (int i = 0; i < list.length; i++) {
|
||||
list.grow(i+1);
|
||||
list.values[i] = ((long)i%100);
|
||||
}
|
||||
|
||||
assertThat(999, equalTo(list.lastIndexOf(99l)));
|
||||
assertThat(99, equalTo(list.indexOf(99l)));
|
||||
|
||||
assertThat(-1, equalTo(list.lastIndexOf(100l)));
|
||||
assertThat(-1, equalTo(list.indexOf(100l)));
|
||||
}
|
||||
|
||||
public void testIsEmpty() {
|
||||
SlicedLongList list = new SlicedLongList(5);
|
||||
assertThat(false, equalTo(list.isEmpty()));
|
||||
list.length = 0;
|
||||
assertThat(true, equalTo(list.isEmpty()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToString() {
|
||||
SlicedLongList list = new SlicedLongList(5);
|
||||
assertThat("[0, 0, 0, 0, 0]", equalTo(list.toString()));
|
||||
for (int i = 0; i < list.length; i++) {
|
||||
list.grow(i+1);
|
||||
list.values[i] = ((long)i);
|
||||
}
|
||||
assertThat("[0, 1, 2, 3, 4]", equalTo(list.toString()));
|
||||
}
|
||||
|
||||
}
|
|
@ -1,147 +0,0 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch 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.common.util;
|
||||
|
||||
import org.apache.lucene.util.ArrayUtil;
|
||||
import org.apache.lucene.util.RamUsageEstimator;
|
||||
import org.elasticsearch.test.ElasticsearchTestCase;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
/**
|
||||
* Tests for {@link SlicedObjectList}
|
||||
*/
|
||||
public class SlicedObjectListTests extends ElasticsearchTestCase {
|
||||
|
||||
public class TestList extends SlicedObjectList<Double> {
|
||||
|
||||
public TestList(int capactiy) {
|
||||
this(new Double[capactiy], 0, capactiy);
|
||||
}
|
||||
|
||||
public TestList(Double[] values, int offset, int length) {
|
||||
super(values, offset, length);
|
||||
}
|
||||
|
||||
public TestList(Double[] values) {
|
||||
super(values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void grow(int newLength) {
|
||||
assertThat(offset, equalTo(0)); // NOTE: senseless if offset != 0
|
||||
if (values.length >= newLength) {
|
||||
return;
|
||||
}
|
||||
final Double[] current = values;
|
||||
values = new Double[ArrayUtil.oversize(newLength, RamUsageEstimator.NUM_BYTES_OBJECT_REF)];
|
||||
System.arraycopy(current, 0, values, 0, current.length);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@Test
|
||||
public void testCapacity() {
|
||||
TestList list = new TestList(5);
|
||||
assertThat(list.length, equalTo(5));
|
||||
assertThat(list.offset, equalTo(0));
|
||||
assertThat(list.values.length, equalTo(5));
|
||||
assertThat(list.size(), equalTo(5));
|
||||
|
||||
|
||||
list = new TestList(new Double[10], 5, 5);
|
||||
assertThat(list.length, equalTo(5));
|
||||
assertThat(list.offset, equalTo(5));
|
||||
assertThat(list.size(), equalTo(5));
|
||||
assertThat(list.values.length, equalTo(10));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGrow() {
|
||||
TestList list = new TestList(5);
|
||||
list.length = 1000;
|
||||
for (int i = 0; i < list.length; i++) {
|
||||
list.grow(i+1);
|
||||
list.values[i] = ((double)i);
|
||||
}
|
||||
int expected = 0;
|
||||
for (Double d : list) {
|
||||
assertThat((double)expected++, equalTo(d));
|
||||
}
|
||||
|
||||
for (int i = 0; i < list.length; i++) {
|
||||
assertThat((double)i, equalTo(list.get(i)));
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
for (int i = list.offset; i < list.offset+list.length; i++) {
|
||||
assertThat((double)count++, equalTo(list.values[i]));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIndexOf() {
|
||||
TestList list = new TestList(5);
|
||||
list.length = 1000;
|
||||
for (int i = 0; i < list.length; i++) {
|
||||
list.grow(i+1);
|
||||
list.values[i] = ((double)i%100);
|
||||
}
|
||||
|
||||
assertThat(999, equalTo(list.lastIndexOf(99.0d)));
|
||||
assertThat(99, equalTo(list.indexOf(99.0d)));
|
||||
|
||||
assertThat(-1, equalTo(list.lastIndexOf(100.0d)));
|
||||
assertThat(-1, equalTo(list.indexOf(100.0d)));
|
||||
}
|
||||
|
||||
public void testIsEmpty() {
|
||||
TestList list = new TestList(5);
|
||||
assertThat(false, equalTo(list.isEmpty()));
|
||||
list.length = 0;
|
||||
assertThat(true, equalTo(list.isEmpty()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSet() {
|
||||
TestList list = new TestList(5);
|
||||
try {
|
||||
list.set(0, (double)4);
|
||||
fail();
|
||||
} catch (UnsupportedOperationException ex) {
|
||||
}
|
||||
try {
|
||||
list.add((double)4);
|
||||
fail();
|
||||
} catch (UnsupportedOperationException ex) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToString() {
|
||||
TestList list = new TestList(5);
|
||||
assertThat("[null, null, null, null, null]", equalTo(list.toString()));
|
||||
for (int i = 0; i < list.length; i++) {
|
||||
list.grow(i+1);
|
||||
list.values[i] = ((double)i);
|
||||
}
|
||||
assertThat("[0.0, 1.0, 2.0, 3.0, 4.0]", equalTo(list.toString()));
|
||||
}
|
||||
|
||||
}
|
|
@ -664,7 +664,7 @@ public class DoubleTermsTests extends AbstractTermsTests {
|
|||
SearchResponse response = client().prepareSearch("idx").setTypes("type")
|
||||
.addAggregation(terms("terms")
|
||||
.collectMode(randomFrom(SubAggCollectionMode.values()))
|
||||
.script("doc['" + MULTI_VALUED_FIELD_NAME + "'].values"))
|
||||
.script("doc['" + MULTI_VALUED_FIELD_NAME + "']"))
|
||||
.execute().actionGet();
|
||||
|
||||
assertSearchResponse(response);
|
||||
|
@ -699,7 +699,7 @@ public class DoubleTermsTests extends AbstractTermsTests {
|
|||
SearchResponse response = client().prepareSearch("idx").setTypes("type")
|
||||
.addAggregation(terms("terms")
|
||||
.collectMode(randomFrom(SubAggCollectionMode.values()))
|
||||
.script("doc['" + MULTI_VALUED_FIELD_NAME + "'].values")
|
||||
.script("doc['" + MULTI_VALUED_FIELD_NAME + "']")
|
||||
.subAggregation(sum("sum")))
|
||||
.execute().actionGet();
|
||||
|
||||
|
@ -717,7 +717,7 @@ public class DoubleTermsTests extends AbstractTermsTests {
|
|||
SearchResponse response = client().prepareSearch("idx").setTypes("type")
|
||||
.addAggregation(terms("terms")
|
||||
.collectMode(randomFrom(SubAggCollectionMode.values()))
|
||||
.script("doc['" + MULTI_VALUED_FIELD_NAME + "'].values")
|
||||
.script("doc['" + MULTI_VALUED_FIELD_NAME + "']")
|
||||
.valueType(Terms.ValueType.DOUBLE)
|
||||
.subAggregation(sum("sum")))
|
||||
.execute().actionGet();
|
||||
|
|
|
@ -770,7 +770,7 @@ public class HistogramTests extends ElasticsearchIntegrationTest {
|
|||
@Test
|
||||
public void script_MultiValued() throws Exception {
|
||||
SearchResponse response = client().prepareSearch("idx")
|
||||
.addAggregation(histogram("histo").script("doc['" + MULTI_VALUED_FIELD_NAME + "'].values").interval(interval))
|
||||
.addAggregation(histogram("histo").script("doc['" + MULTI_VALUED_FIELD_NAME + "']").interval(interval))
|
||||
.execute().actionGet();
|
||||
|
||||
assertSearchResponse(response);
|
||||
|
@ -792,7 +792,7 @@ public class HistogramTests extends ElasticsearchIntegrationTest {
|
|||
@Test
|
||||
public void script_MultiValued_WithAggregatorInherited() throws Exception {
|
||||
SearchResponse response = client().prepareSearch("idx")
|
||||
.addAggregation(histogram("histo").script("doc['" + MULTI_VALUED_FIELD_NAME + "'].values").interval(interval)
|
||||
.addAggregation(histogram("histo").script("doc['" + MULTI_VALUED_FIELD_NAME + "']").interval(interval)
|
||||
.subAggregation(sum("sum")))
|
||||
.execute().actionGet();
|
||||
|
||||
|
|
|
@ -664,7 +664,7 @@ public class LongTermsTests extends AbstractTermsTests {
|
|||
SearchResponse response = client().prepareSearch("idx").setTypes("type")
|
||||
.addAggregation(terms("terms")
|
||||
.collectMode(randomFrom(SubAggCollectionMode.values()))
|
||||
.script("doc['" + MULTI_VALUED_FIELD_NAME + "'].values"))
|
||||
.script("doc['" + MULTI_VALUED_FIELD_NAME + "']"))
|
||||
.execute().actionGet();
|
||||
|
||||
assertSearchResponse(response);
|
||||
|
@ -699,7 +699,7 @@ public class LongTermsTests extends AbstractTermsTests {
|
|||
SearchResponse response = client().prepareSearch("idx").setTypes("type")
|
||||
.addAggregation(terms("terms")
|
||||
.collectMode(randomFrom(SubAggCollectionMode.values()))
|
||||
.script("doc['" + MULTI_VALUED_FIELD_NAME + "'].values")
|
||||
.script("doc['" + MULTI_VALUED_FIELD_NAME + "']")
|
||||
.subAggregation(sum("sum")))
|
||||
.execute().actionGet();
|
||||
|
||||
|
@ -715,7 +715,7 @@ public class LongTermsTests extends AbstractTermsTests {
|
|||
SearchResponse response = client().prepareSearch("idx").setTypes("type")
|
||||
.addAggregation(terms("terms")
|
||||
.collectMode(randomFrom(SubAggCollectionMode.values()))
|
||||
.script("doc['" + MULTI_VALUED_FIELD_NAME + "'].values")
|
||||
.script("doc['" + MULTI_VALUED_FIELD_NAME + "']")
|
||||
.valueType(Terms.ValueType.LONG)
|
||||
.subAggregation(sum("sum")))
|
||||
.execute().actionGet();
|
||||
|
|
|
@ -770,6 +770,34 @@ public class StringTermsTests extends AbstractTermsTests {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void multiValuedScript() throws Exception {
|
||||
SearchResponse response = client().prepareSearch("idx").setTypes("type")
|
||||
.addAggregation(terms("terms")
|
||||
.executionHint(randomExecutionHint())
|
||||
.script("doc['" + MULTI_VALUED_FIELD_NAME + "']")
|
||||
.collectMode(randomFrom(SubAggCollectionMode.values())))
|
||||
.execute().actionGet();
|
||||
|
||||
assertSearchResponse(response);
|
||||
|
||||
Terms terms = response.getAggregations().get("terms");
|
||||
assertThat(terms, notNullValue());
|
||||
assertThat(terms.getName(), equalTo("terms"));
|
||||
assertThat(terms.getBuckets().size(), equalTo(6));
|
||||
|
||||
for (int i = 0; i < 6; i++) {
|
||||
Terms.Bucket bucket = terms.getBucketByKey("val" + i);
|
||||
assertThat(bucket, notNullValue());
|
||||
assertThat(key(bucket), equalTo("val" + i));
|
||||
if (i == 0 || i == 5) {
|
||||
assertThat(bucket.getDocCount(), equalTo(1l));
|
||||
} else {
|
||||
assertThat(bucket.getDocCount(), equalTo(2l));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void multiValuedField_WithValueScript() throws Exception {
|
||||
SearchResponse response = client().prepareSearch("idx").setTypes("type")
|
||||
|
@ -935,7 +963,7 @@ public class StringTermsTests extends AbstractTermsTests {
|
|||
.addAggregation(terms("terms")
|
||||
.collectMode(randomFrom(SubAggCollectionMode.values()))
|
||||
.executionHint(randomExecutionHint())
|
||||
.script("doc['" + MULTI_VALUED_FIELD_NAME + "'].values"))
|
||||
.script("doc['" + MULTI_VALUED_FIELD_NAME + "']"))
|
||||
.execute().actionGet();
|
||||
|
||||
assertSearchResponse(response);
|
||||
|
@ -963,7 +991,7 @@ public class StringTermsTests extends AbstractTermsTests {
|
|||
.addAggregation(terms("terms")
|
||||
.collectMode(randomFrom(SubAggCollectionMode.values()))
|
||||
.executionHint(randomExecutionHint())
|
||||
.script("doc['" + MULTI_VALUED_FIELD_NAME + "'].values")
|
||||
.script("doc['" + MULTI_VALUED_FIELD_NAME + "']")
|
||||
.subAggregation(count("count")))
|
||||
.execute().actionGet();
|
||||
|
||||
|
|
|
@ -296,7 +296,7 @@ public class MinTests extends AbstractNumericTests {
|
|||
public void testScript_MultiValued_WithParams() throws Exception {
|
||||
SearchResponse searchResponse = client().prepareSearch("idx")
|
||||
.setQuery(matchAllQuery())
|
||||
.addAggregation(min("min").script("List values = doc['values'].values; double[] res = new double[values.length]; for (int i = 0; i < res.length; i++) { res[i] = values.get(i) - dec; }; return res;").param("dec", 1))
|
||||
.addAggregation(min("min").script("List values = doc['values'].values; double[] res = new double[values.size()]; for (int i = 0; i < res.length; i++) { res[i] = values.get(i) - dec; }; return res;").param("dec", 1))
|
||||
.execute().actionGet();
|
||||
|
||||
assertThat(searchResponse.getHits().getTotalHits(), equalTo(10l));
|
||||
|
|
|
@ -398,7 +398,7 @@ public class PercentileRanksTests extends AbstractNumericTests {
|
|||
SearchResponse searchResponse = client().prepareSearch("idx")
|
||||
.setQuery(matchAllQuery())
|
||||
.addAggregation(randomCompression(percentileRanks("percentile_ranks"))
|
||||
.script("List values = doc['values'].values; double[] res = new double[values.length]; for (int i = 0; i < res.length; i++) { res[i] = values.get(i) - dec; }; return res;").param("dec", 1)
|
||||
.script("List values = doc['values'].values; double[] res = new double[values.size()]; for (int i = 0; i < res.length; i++) { res[i] = values.get(i) - dec; }; return res;").param("dec", 1)
|
||||
.percentiles(pcts))
|
||||
.execute().actionGet();
|
||||
|
||||
|
|
|
@ -381,7 +381,7 @@ public class PercentilesTests extends AbstractNumericTests {
|
|||
SearchResponse searchResponse = client().prepareSearch("idx")
|
||||
.setQuery(matchAllQuery())
|
||||
.addAggregation(randomCompression(percentiles("percentiles"))
|
||||
.script("List values = doc['values'].values; double[] res = new double[values.length]; for (int i = 0; i < res.length; i++) { res[i] = values.get(i) - dec; }; return res;").param("dec", 1)
|
||||
.script("List values = doc['values'].values; double[] res = new double[values.size()]; for (int i = 0; i < res.length; i++) { res[i] = values.get(i) - dec; }; return res;").param("dec", 1)
|
||||
.percentiles(pcts))
|
||||
.execute().actionGet();
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ import org.elasticsearch.common.joda.Joda;
|
|||
import org.elasticsearch.common.settings.ImmutableSettings;
|
||||
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||
import org.elasticsearch.rest.RestStatus;
|
||||
import org.elasticsearch.search.SearchHit;
|
||||
import org.elasticsearch.search.SearchHitField;
|
||||
import org.elasticsearch.search.sort.SortOrder;
|
||||
import org.elasticsearch.test.ElasticsearchIntegrationTest;
|
||||
|
@ -40,7 +41,9 @@ import org.joda.time.DateTime;
|
|||
import org.joda.time.DateTimeZone;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
@ -48,10 +51,15 @@ import java.util.concurrent.ExecutionException;
|
|||
import static org.elasticsearch.client.Requests.refreshRequest;
|
||||
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
|
||||
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
|
||||
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
|
||||
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertFailures;
|
||||
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount;
|
||||
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertNoFailures;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSearchResponse;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -563,4 +571,43 @@ public class SearchFieldsTests extends ElasticsearchIntegrationTest {
|
|||
assertThat(searchResponse.getHits().getAt(0).fields().get("boolean_field").value().toString(), equalTo("T"));
|
||||
|
||||
}
|
||||
|
||||
public void testScriptFields() throws Exception {
|
||||
assertAcked(prepareCreate("index").addMapping("type",
|
||||
"s", "type=string,index=not_analyzed",
|
||||
"l", "type=long",
|
||||
"d", "type=double",
|
||||
"ms", "type=string,index=not_analyzed",
|
||||
"ml", "type=long",
|
||||
"md", "type=double").get());
|
||||
final int numDocs = randomIntBetween(3, 8);
|
||||
List<IndexRequestBuilder> reqs = new ArrayList<>();
|
||||
for (int i = 0; i < numDocs; ++i) {
|
||||
reqs.add(client().prepareIndex("index", "type", Integer.toString(i)).setSource(
|
||||
"s", Integer.toString(i),
|
||||
"ms", new String[] {Integer.toString(i), Integer.toString(i+1)},
|
||||
"l", i,
|
||||
"ml", new long[] {i, i+1},
|
||||
"d", i,
|
||||
"md", new double[] {i, i+1}));
|
||||
}
|
||||
indexRandom(true, reqs);
|
||||
ensureSearchable();
|
||||
SearchRequestBuilder req = client().prepareSearch("index");
|
||||
for (String field : Arrays.asList("s", "ms", "l", "ml", "d", "md")) {
|
||||
req.addScriptField(field, "doc['" + field + "'].values");
|
||||
}
|
||||
SearchResponse resp = req.get();
|
||||
assertSearchResponse(resp);
|
||||
for (SearchHit hit : resp.getHits().getHits()) {
|
||||
final int id = Integer.parseInt(hit.getId());
|
||||
Map<String, SearchHitField> fields = hit.getFields();
|
||||
assertThat(fields.get("s").getValues(), equalTo(Collections.<Object>singletonList(Integer.toString(id))));
|
||||
assertThat(fields.get("l").getValues(), equalTo(Collections.<Object>singletonList((long) id)));
|
||||
assertThat(fields.get("d").getValues(), equalTo(Collections.<Object>singletonList((double) id)));
|
||||
assertThat(fields.get("ms").getValues(), equalTo(Arrays.<Object>asList(Integer.toString(id), Integer.toString(id + 1))));
|
||||
assertThat(fields.get("ml").getValues(), equalTo(Arrays.<Object>asList((long) id, id+1L)));
|
||||
assertThat(fields.get("md").getValues(), equalTo(Arrays.<Object>asList((double) id, id+1d)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue