Skip to content

Commit a2d7269

Browse files
committed
Expose field level field data statistics
closes elastic#2889
1 parent 3b7a195 commit a2d7269

File tree

18 files changed

+340
-147
lines changed

18 files changed

+340
-147
lines changed

src/main/java/org/elasticsearch/action/admin/cluster/node/stats/NodesStatsResponse.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import org.elasticsearch.common.io.stream.StreamOutput;
2626
import org.elasticsearch.common.xcontent.ToXContent;
2727
import org.elasticsearch.common.xcontent.XContentBuilder;
28+
import org.elasticsearch.common.xcontent.XContentFactory;
2829

2930
import java.io.IOException;
3031
import java.util.Map;
@@ -118,4 +119,17 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
118119

119120
return builder;
120121
}
122+
123+
@Override
124+
public String toString() {
125+
try {
126+
XContentBuilder builder = XContentFactory.jsonBuilder().prettyPrint();
127+
builder.startObject();
128+
toXContent(builder, EMPTY_PARAMS);
129+
builder.endObject();
130+
return builder.string();
131+
} catch (IOException e) {
132+
return "{ \"error\" : \"" + e.getMessage() + "\"}";
133+
}
134+
}
121135
}

src/main/java/org/elasticsearch/action/admin/indices/stats/CommonStatsFlags.java

Lines changed: 46 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,11 @@
2828

2929
/**
3030
*/
31-
public class CommonStatsFlags implements Streamable {
31+
public class CommonStatsFlags implements Streamable, Cloneable {
3232
private EnumSet<Flag> flags = EnumSet.of(Flag.Docs, Flag.Store, Flag.Indexing, Flag.Get, Flag.Search);
3333
private String[] types = null;
3434
private String[] groups = null;
35+
private String[] fieldDataFields = null;
3536

3637
/**
3738
* Sets all flags to return all stats.
@@ -40,6 +41,7 @@ public CommonStatsFlags all() {
4041
flags = EnumSet.allOf(Flag.class);
4142
types = null;
4243
groups = null;
44+
fieldDataFields = null;
4345
return this;
4446
}
4547

@@ -50,13 +52,14 @@ public CommonStatsFlags clear() {
5052
flags = EnumSet.noneOf(Flag.class);
5153
types = null;
5254
groups = null;
55+
fieldDataFields = null;
5356
return this;
5457
}
5558

5659
public boolean anySet() {
5760
return !flags.isEmpty();
5861
}
59-
62+
6063
public Flag[] getFlags() {
6164
return flags.toArray(new Flag[flags.size()]);
6265
}
@@ -90,19 +93,33 @@ public CommonStatsFlags groups(String... groups) {
9093
public String[] groups() {
9194
return this.groups;
9295
}
93-
96+
97+
/**
98+
* Sets specific search group stats to retrieve the stats for. Mainly affects search
99+
* when enabled.
100+
*/
101+
public CommonStatsFlags fieldDataFields(String... fieldDataFields) {
102+
this.fieldDataFields = fieldDataFields;
103+
return this;
104+
}
105+
106+
public String[] fieldDataFields() {
107+
return this.fieldDataFields;
108+
}
109+
110+
94111
public boolean isSet(Flag flag) {
95112
return flags.contains(flag);
96113
}
97-
114+
98115
boolean unSet(Flag flag) {
99116
return flags.remove(flag);
100117
}
101-
118+
102119
void set(Flag flag) {
103120
flags.add(flag);
104121
}
105-
122+
106123
public CommonStatsFlags set(Flag flag, boolean add) {
107124
if (add) {
108125
set(flag);
@@ -125,49 +142,37 @@ public void writeTo(StreamOutput out) throws IOException {
125142
longFlags |= (1 << flag.ordinal());
126143
}
127144
out.writeLong(longFlags);
128-
if (types == null) {
129-
out.writeVInt(0);
130-
} else {
131-
out.writeVInt(types.length);
132-
for (String type : types) {
133-
out.writeString(type);
134-
}
135-
}
136-
if (groups == null) {
137-
out.writeVInt(0);
138-
} else {
139-
out.writeVInt(groups.length);
140-
for (String group : groups) {
141-
out.writeString(group);
142-
}
143-
}
145+
146+
out.writeStringArrayNullable(types);
147+
out.writeStringArrayNullable(groups);
148+
out.writeStringArrayNullable(fieldDataFields);
144149
}
145150

146151
@Override
147152
public void readFrom(StreamInput in) throws IOException {
148153
final long longFlags = in.readLong();
149154
flags.clear();
150-
for(Flag flag : Flag.values()) {
155+
for (Flag flag : Flag.values()) {
151156
if ((longFlags & (1 << flag.ordinal())) != 0) {
152157
flags.add(flag);
153158
}
154159
}
155-
int size = in.readVInt();
156-
if (size > 0) {
157-
types = new String[size];
158-
for (int i = 0; i < size; i++) {
159-
types[i] = in.readString();
160-
}
161-
}
162-
size = in.readVInt();
163-
if (size > 0) {
164-
groups = new String[size];
165-
for (int i = 0; i < size; i++) {
166-
groups[i] = in.readString();
167-
}
160+
types = in.readStringArray();
161+
groups = in.readStringArray();
162+
fieldDataFields = in.readStringArray();
163+
}
164+
165+
@Override
166+
public CommonStatsFlags clone() {
167+
try {
168+
CommonStatsFlags cloned = (CommonStatsFlags) super.clone();
169+
cloned.flags = flags.clone();
170+
return cloned;
171+
} catch (CloneNotSupportedException e) {
172+
throw new AssertionError(e);
168173
}
169174
}
170-
175+
171176
public static enum Flag {
172177
// Do not change the order of these flags we use
173178
// the ordinal for encoding! Only append to the end!
@@ -183,16 +188,16 @@ public static enum Flag {
183188
FieldData("fielddata"),
184189
Docs("docs"),
185190
Warmer("warmer");
186-
191+
187192
private final String restName;
188-
193+
189194
Flag(String restName) {
190195
this.restName = restName;
191196
}
192-
197+
193198
public String getRestName() {
194199
return restName;
195200
}
196-
201+
197202
}
198203
}

src/main/java/org/elasticsearch/action/admin/indices/stats/IndicesStatsRequest.java

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,13 @@
1919

2020
package org.elasticsearch.action.admin.indices.stats;
2121

22-
import java.io.IOException;
23-
2422
import org.elasticsearch.action.admin.indices.stats.CommonStatsFlags.Flag;
2523
import org.elasticsearch.action.support.broadcast.BroadcastOperationRequest;
2624
import org.elasticsearch.common.io.stream.StreamInput;
2725
import org.elasticsearch.common.io.stream.StreamOutput;
2826

27+
import java.io.IOException;
28+
2929
/**
3030
* A request to get indices level stats. Allow to enable different stats to be returned.
3131
* <p/>
@@ -141,7 +141,7 @@ public boolean merge() {
141141
}
142142

143143
public IndicesStatsRequest refresh(boolean refresh) {
144-
flags.set(Flag.Refresh, refresh);
144+
flags.set(Flag.Refresh, refresh);
145145
return this;
146146
}
147147

@@ -194,6 +194,15 @@ public boolean fieldData() {
194194
return flags.isSet(Flag.FieldData);
195195
}
196196

197+
public IndicesStatsRequest fieldDataFields(String... fieldDataFields) {
198+
flags.fieldDataFields(fieldDataFields);
199+
return this;
200+
}
201+
202+
public String[] fieldDataFields() {
203+
return flags.fieldDataFields();
204+
}
205+
197206
@Override
198207
public void writeTo(StreamOutput out) throws IOException {
199208
super.writeTo(out);

src/main/java/org/elasticsearch/action/admin/indices/stats/IndicesStatsRequestBuilder.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,11 @@ public IndicesStatsRequestBuilder setFieldData(boolean fieldData) {
129129
return this;
130130
}
131131

132+
public IndicesStatsRequestBuilder setFieldDataFields(String... fields) {
133+
request.fieldDataFields(fields);
134+
return this;
135+
}
136+
132137
@Override
133138
protected void doExecute(ActionListener<IndicesStatsResponse> listener) {
134139
((IndicesAdminClient) client).stats(request, listener);

src/main/java/org/elasticsearch/action/admin/indices/stats/IndicesStatsResponse.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import org.elasticsearch.common.xcontent.ToXContent;
3131
import org.elasticsearch.common.xcontent.XContentBuilder;
3232
import org.elasticsearch.common.xcontent.XContentBuilderString;
33+
import org.elasticsearch.common.xcontent.XContentFactory;
3334

3435
import java.io.IOException;
3536
import java.util.List;
@@ -202,4 +203,17 @@ static final class Fields {
202203
static final XContentBuilderString NODE = new XContentBuilderString("node");
203204
static final XContentBuilderString RELOCATING_NODE = new XContentBuilderString("relocating_node");
204205
}
206+
207+
@Override
208+
public String toString() {
209+
try {
210+
XContentBuilder builder = XContentFactory.jsonBuilder().prettyPrint();
211+
builder.startObject();
212+
toXContent(builder, EMPTY_PARAMS);
213+
builder.endObject();
214+
return builder.string();
215+
} catch (IOException e) {
216+
return "{ \"error\" : \"" + e.getMessage() + "\"}";
217+
}
218+
}
205219
}

src/main/java/org/elasticsearch/action/admin/indices/stats/TransportIndicesStatsAction.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ protected ShardStats shardOperation(IndexShardStatsRequest request) throws Elast
179179
stats.stats.idCache = indexShard.idCacheStats();
180180
}
181181
if (request.request.fieldData()) {
182-
stats.stats.fieldData = indexShard.fieldDataStats();
182+
stats.stats.fieldData = indexShard.fieldDataStats(request.request.fieldDataFields());
183183
}
184184

185185
return stats;

src/main/java/org/elasticsearch/common/path/PathTrie.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,9 @@ public T retrieve(String[] path, int index, Map<String, String> params) {
171171
}
172172

173173
if (index == (path.length - 1)) {
174+
if (params != null && node.isNamedWildcard()) {
175+
put(params, node.namedWildcard(), token);
176+
}
174177
return node.value;
175178
}
176179

src/main/java/org/elasticsearch/index/fielddata/FieldDataStats.java

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919

2020
package org.elasticsearch.index.fielddata;
2121

22+
import gnu.trove.iterator.TObjectLongIterator;
23+
import gnu.trove.map.hash.TObjectLongHashMap;
24+
import org.elasticsearch.common.Nullable;
2225
import org.elasticsearch.common.io.stream.StreamInput;
2326
import org.elasticsearch.common.io.stream.StreamOutput;
2427
import org.elasticsearch.common.io.stream.Streamable;
@@ -35,19 +38,29 @@ public class FieldDataStats implements Streamable, ToXContent {
3538

3639
long memorySize;
3740
long evictions;
41+
@Nullable
42+
TObjectLongHashMap<String> fields;
3843

3944
public FieldDataStats() {
4045

4146
}
4247

43-
public FieldDataStats(long memorySize, long evictions) {
48+
public FieldDataStats(long memorySize, long evictions, @Nullable TObjectLongHashMap<String> fields) {
4449
this.memorySize = memorySize;
4550
this.evictions = evictions;
51+
this.fields = fields;
4652
}
4753

4854
public void add(FieldDataStats stats) {
4955
this.memorySize += stats.memorySize;
5056
this.evictions += stats.evictions;
57+
if (stats.fields != null) {
58+
if (fields == null) fields = new TObjectLongHashMap<String>();
59+
for (TObjectLongIterator<String> it = stats.fields.iterator(); it.hasNext(); ) {
60+
it.advance();
61+
fields.adjustOrPutValue(it.key(), it.value(), it.value());
62+
}
63+
}
5164
}
5265

5366
public long getMemorySizeInBytes() {
@@ -62,6 +75,11 @@ public long getEvictions() {
6275
return this.evictions;
6376
}
6477

78+
@Nullable
79+
public TObjectLongHashMap<String> getFields() {
80+
return fields;
81+
}
82+
6583
public static FieldDataStats readFieldDataStats(StreamInput in) throws IOException {
6684
FieldDataStats stats = new FieldDataStats();
6785
stats.readFrom(in);
@@ -72,12 +90,30 @@ public static FieldDataStats readFieldDataStats(StreamInput in) throws IOExcepti
7290
public void readFrom(StreamInput in) throws IOException {
7391
memorySize = in.readVLong();
7492
evictions = in.readVLong();
93+
if (in.readBoolean()) {
94+
int size = in.readVInt();
95+
fields = new TObjectLongHashMap<String>(size);
96+
for (int i = 0; i < size; i++) {
97+
fields.put(in.readString(), in.readVLong());
98+
}
99+
}
75100
}
76101

77102
@Override
78103
public void writeTo(StreamOutput out) throws IOException {
79104
out.writeVLong(memorySize);
80105
out.writeVLong(evictions);
106+
if (fields == null) {
107+
out.writeBoolean(false);
108+
} else {
109+
out.writeBoolean(true);
110+
out.writeVInt(fields.size());
111+
for (TObjectLongIterator<String> it = fields.iterator(); it.hasNext(); ) {
112+
it.advance();
113+
out.writeString(it.key());
114+
out.writeVLong(it.value());
115+
}
116+
}
81117
}
82118

83119
@Override
@@ -86,6 +122,17 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
86122
builder.field(Fields.MEMORY_SIZE, getMemorySize().toString());
87123
builder.field(Fields.MEMORY_SIZE_IN_BYTES, memorySize);
88124
builder.field(Fields.EVICTIONS, getEvictions());
125+
if (fields != null) {
126+
builder.startObject(Fields.FIELDS);
127+
for (TObjectLongIterator<String> it = fields.iterator(); it.hasNext(); ) {
128+
it.advance();
129+
builder.startObject(it.key(), XContentBuilder.FieldCaseConversion.NONE);
130+
builder.field(Fields.MEMORY_SIZE, new ByteSizeValue(it.value()).toString());
131+
builder.field(Fields.MEMORY_SIZE_IN_BYTES, it.value());
132+
builder.endObject();
133+
}
134+
builder.endObject();
135+
}
89136
builder.endObject();
90137
return builder;
91138
}
@@ -95,5 +142,6 @@ static final class Fields {
95142
static final XContentBuilderString MEMORY_SIZE = new XContentBuilderString("memory_size");
96143
static final XContentBuilderString MEMORY_SIZE_IN_BYTES = new XContentBuilderString("memory_size_in_bytes");
97144
static final XContentBuilderString EVICTIONS = new XContentBuilderString("evictions");
145+
static final XContentBuilderString FIELDS = new XContentBuilderString("fields");
98146
}
99147
}

0 commit comments

Comments
 (0)