diff --git a/server/src/main/java/org/elasticsearch/index/fielddata/ScriptDocValues.java b/server/src/main/java/org/elasticsearch/index/fielddata/ScriptDocValues.java index 080ef97d5f86d..1dfb10098b8b5 100644 --- a/server/src/main/java/org/elasticsearch/index/fielddata/ScriptDocValues.java +++ b/server/src/main/java/org/elasticsearch/index/fielddata/ScriptDocValues.java @@ -481,25 +481,30 @@ protected void resize(int newSize) { public int size() { return count; } - } - public static final class Strings extends BinaryScriptDocValues { - + public static class Strings extends BinaryScriptDocValues { public Strings(SortedBinaryDocValues in) { super(in); } @Override - public String get(int index) { + public final String get(int index) { if (count == 0) { throw new IllegalStateException("A document doesn't have a value for a field! " + "Use doc[].size()==0 to check if a document is missing a field!"); } - return values[index].get().utf8ToString(); + return bytesToString(values[index].get()); + } + + /** + * Convert the stored bytes to a String. + */ + protected String bytesToString(BytesRef bytes) { + return bytes.utf8ToString(); } - public String getValue() { + public final String getValue() { return get(0); } } diff --git a/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/fielddata/ScriptIpFieldData.java b/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/fielddata/ScriptIpFieldData.java index 52b6b9d05ca77..e9e7e86b3ab32 100644 --- a/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/fielddata/ScriptIpFieldData.java +++ b/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/fielddata/ScriptIpFieldData.java @@ -8,6 +8,7 @@ import org.apache.lucene.document.InetAddressPoint; import org.apache.lucene.index.LeafReaderContext; +import org.apache.lucene.util.BytesRef; import org.elasticsearch.common.bytes.BytesArray; import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.network.InetAddresses; @@ -22,7 +23,6 @@ import org.elasticsearch.search.aggregations.support.ValuesSourceType; import org.elasticsearch.xpack.runtimefields.IpScriptFieldScript; -import java.io.IOException; import java.net.InetAddress; public class ScriptIpFieldData extends ScriptBinaryFieldData { @@ -54,7 +54,7 @@ public ScriptBinaryLeafFieldData loadDirect(LeafReaderContext context) throws Ex return new ScriptBinaryLeafFieldData() { @Override public ScriptDocValues getScriptValues() { - return new IpScriptDocValues(script); + return new IpScriptDocValues(getBytesValues()); } @Override @@ -70,46 +70,19 @@ public ValuesSourceType getValuesSourceType() { } /** - * We can't share {@link IpFieldMapper.IpFieldType.IpScriptDocValues} because it - * is based on global ordinals and we don't have those. + * Doc values implementation for ips. We can't share + * {@link IpFieldMapper.IpFieldType.IpScriptDocValues} because it is based + * on global ordinals and we don't have those. */ - public static class IpScriptDocValues extends ScriptDocValues { - private final IpScriptFieldScript script; - - public IpScriptDocValues(IpScriptFieldScript script) { - this.script = script; + public static class IpScriptDocValues extends ScriptDocValues.Strings { + public IpScriptDocValues(SortedBinaryDocValues in) { + super(in); } @Override - public void setNextDocId(int docId) throws IOException { - script.runForDoc(docId); - } - - public String getValue() { - if (size() == 0) { - return null; - } - return get(0); - } - - @Override - public String get(int index) { - if (index >= size()) { - if (size() == 0) { - throw new IllegalStateException( - "A document doesn't have a value for a field! " - + "Use doc[].size()==0 to check if a document is missing a field!" - ); - } - throw new ArrayIndexOutOfBoundsException("There are only [" + size() + "] values."); - } - InetAddress addr = InetAddressPoint.decode(BytesReference.toBytes(new BytesArray(script.values()[index]))); + protected String bytesToString(BytesRef bytes) { + InetAddress addr = InetAddressPoint.decode(BytesReference.toBytes(new BytesArray(bytes))); return InetAddresses.toAddrString(addr); } - - @Override - public int size() { - return script.count(); - } } } diff --git a/x-pack/plugin/src/test/resources/rest-api-spec/test/runtime_fields/50_ip.yml b/x-pack/plugin/src/test/resources/rest-api-spec/test/runtime_fields/50_ip.yml index e572ce7462f30..b24a52b3afc74 100644 --- a/x-pack/plugin/src/test/resources/rest-api-spec/test/runtime_fields/50_ip.yml +++ b/x-pack/plugin/src/test/resources/rest-api-spec/test/runtime_fields/50_ip.yml @@ -111,6 +111,24 @@ setup: - match: {aggregations.ip.buckets.1.key: 26.1.0.0} - match: {aggregations.ip.buckets.1.doc_count: 1} +--- +"use in scripts": + - do: + search: + index: http_logs + body: + aggs: + ip: + terms: + script: + String v = doc['ip'].value; + return v.substring(0, v.indexOf('.')); + - match: {hits.total.value: 6} + - match: {aggregations.ip.buckets.0.key: '247'} + - match: {aggregations.ip.buckets.0.doc_count: 2} + - match: {aggregations.ip.buckets.1.key: '232'} + - match: {aggregations.ip.buckets.1.doc_count: 1} + --- "term query": - do: