Indices / Node Stats: Shard level search stats, closes #1301.
This commit is contained in:
parent
8958e9fd4a
commit
dee1addc17
|
@ -30,6 +30,7 @@ import org.elasticsearch.index.get.GetStats;
|
||||||
import org.elasticsearch.index.indexing.IndexingStats;
|
import org.elasticsearch.index.indexing.IndexingStats;
|
||||||
import org.elasticsearch.index.merge.MergeStats;
|
import org.elasticsearch.index.merge.MergeStats;
|
||||||
import org.elasticsearch.index.refresh.RefreshStats;
|
import org.elasticsearch.index.refresh.RefreshStats;
|
||||||
|
import org.elasticsearch.index.search.stats.SearchStats;
|
||||||
import org.elasticsearch.index.shard.DocsStats;
|
import org.elasticsearch.index.shard.DocsStats;
|
||||||
import org.elasticsearch.index.store.StoreStats;
|
import org.elasticsearch.index.store.StoreStats;
|
||||||
|
|
||||||
|
@ -47,6 +48,8 @@ public class CommonStats implements Streamable, ToXContent {
|
||||||
|
|
||||||
@Nullable GetStats get;
|
@Nullable GetStats get;
|
||||||
|
|
||||||
|
@Nullable SearchStats search;
|
||||||
|
|
||||||
@Nullable MergeStats merge;
|
@Nullable MergeStats merge;
|
||||||
|
|
||||||
@Nullable RefreshStats refresh;
|
@Nullable RefreshStats refresh;
|
||||||
|
@ -86,6 +89,14 @@ public class CommonStats implements Streamable, ToXContent {
|
||||||
} else {
|
} else {
|
||||||
get.add(stats.get());
|
get.add(stats.get());
|
||||||
}
|
}
|
||||||
|
if (search == null) {
|
||||||
|
if (stats.search() != null) {
|
||||||
|
search = new SearchStats();
|
||||||
|
search.add(stats.search());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
search.add(stats.search());
|
||||||
|
}
|
||||||
if (merge == null) {
|
if (merge == null) {
|
||||||
if (stats.merge() != null) {
|
if (stats.merge() != null) {
|
||||||
merge = new MergeStats();
|
merge = new MergeStats();
|
||||||
|
@ -144,6 +155,14 @@ public class CommonStats implements Streamable, ToXContent {
|
||||||
return get;
|
return get;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable public SearchStats search() {
|
||||||
|
return search;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable public SearchStats getSearch() {
|
||||||
|
return search;
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable public MergeStats merge() {
|
@Nullable public MergeStats merge() {
|
||||||
return merge;
|
return merge;
|
||||||
}
|
}
|
||||||
|
@ -187,6 +206,9 @@ public class CommonStats implements Streamable, ToXContent {
|
||||||
if (in.readBoolean()) {
|
if (in.readBoolean()) {
|
||||||
get = GetStats.readGetStats(in);
|
get = GetStats.readGetStats(in);
|
||||||
}
|
}
|
||||||
|
if (in.readBoolean()) {
|
||||||
|
search = SearchStats.readSearchStats(in);
|
||||||
|
}
|
||||||
if (in.readBoolean()) {
|
if (in.readBoolean()) {
|
||||||
merge = MergeStats.readMergeStats(in);
|
merge = MergeStats.readMergeStats(in);
|
||||||
}
|
}
|
||||||
|
@ -223,6 +245,12 @@ public class CommonStats implements Streamable, ToXContent {
|
||||||
out.writeBoolean(true);
|
out.writeBoolean(true);
|
||||||
get.writeTo(out);
|
get.writeTo(out);
|
||||||
}
|
}
|
||||||
|
if (search == null) {
|
||||||
|
out.writeBoolean(false);
|
||||||
|
} else {
|
||||||
|
out.writeBoolean(true);
|
||||||
|
search.writeTo(out);
|
||||||
|
}
|
||||||
if (merge == null) {
|
if (merge == null) {
|
||||||
out.writeBoolean(false);
|
out.writeBoolean(false);
|
||||||
} else {
|
} else {
|
||||||
|
@ -257,6 +285,9 @@ public class CommonStats implements Streamable, ToXContent {
|
||||||
if (get != null) {
|
if (get != null) {
|
||||||
get.toXContent(builder, params);
|
get.toXContent(builder, params);
|
||||||
}
|
}
|
||||||
|
if (search != null) {
|
||||||
|
search.toXContent(builder, params);
|
||||||
|
}
|
||||||
if (merge != null) {
|
if (merge != null) {
|
||||||
merge.toXContent(builder, params);
|
merge.toXContent(builder, params);
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,10 +40,12 @@ public class IndicesStatsRequest extends BroadcastOperationRequest {
|
||||||
private boolean store = true;
|
private boolean store = true;
|
||||||
private boolean indexing = true;
|
private boolean indexing = true;
|
||||||
private boolean get = true;
|
private boolean get = true;
|
||||||
|
private boolean search = true;
|
||||||
private boolean merge = false;
|
private boolean merge = false;
|
||||||
private boolean refresh = false;
|
private boolean refresh = false;
|
||||||
private boolean flush = false;
|
private boolean flush = false;
|
||||||
private String[] types = null;
|
private String[] types = null;
|
||||||
|
private String[] groups = null;
|
||||||
|
|
||||||
public IndicesStatsRequest indices(String... indices) {
|
public IndicesStatsRequest indices(String... indices) {
|
||||||
this.indices = indices;
|
this.indices = indices;
|
||||||
|
@ -58,9 +60,12 @@ public class IndicesStatsRequest extends BroadcastOperationRequest {
|
||||||
store = false;
|
store = false;
|
||||||
get = false;
|
get = false;
|
||||||
indexing = false;
|
indexing = false;
|
||||||
|
search = false;
|
||||||
merge = false;
|
merge = false;
|
||||||
refresh = false;
|
refresh = false;
|
||||||
flush = false;
|
flush = false;
|
||||||
|
types = null;
|
||||||
|
groups = null;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,6 +86,19 @@ public class IndicesStatsRequest extends BroadcastOperationRequest {
|
||||||
return this.types;
|
return this.types;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets specific search group stats to retrieve the stats for. Mainly affects search
|
||||||
|
* when enabled.
|
||||||
|
*/
|
||||||
|
public IndicesStatsRequest groups(String... groups) {
|
||||||
|
this.groups = groups;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String[] groups() {
|
||||||
|
return this.groups;
|
||||||
|
}
|
||||||
|
|
||||||
public IndicesStatsRequest docs(boolean docs) {
|
public IndicesStatsRequest docs(boolean docs) {
|
||||||
this.docs = docs;
|
this.docs = docs;
|
||||||
return this;
|
return this;
|
||||||
|
@ -117,6 +135,15 @@ public class IndicesStatsRequest extends BroadcastOperationRequest {
|
||||||
return this.get;
|
return this.get;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IndicesStatsRequest search(boolean search) {
|
||||||
|
this.search = search;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean search() {
|
||||||
|
return this.search;
|
||||||
|
}
|
||||||
|
|
||||||
public IndicesStatsRequest merge(boolean merge) {
|
public IndicesStatsRequest merge(boolean merge) {
|
||||||
this.merge = merge;
|
this.merge = merge;
|
||||||
return this;
|
return this;
|
||||||
|
@ -150,6 +177,7 @@ public class IndicesStatsRequest extends BroadcastOperationRequest {
|
||||||
out.writeBoolean(store);
|
out.writeBoolean(store);
|
||||||
out.writeBoolean(indexing);
|
out.writeBoolean(indexing);
|
||||||
out.writeBoolean(get);
|
out.writeBoolean(get);
|
||||||
|
out.writeBoolean(search);
|
||||||
out.writeBoolean(merge);
|
out.writeBoolean(merge);
|
||||||
out.writeBoolean(flush);
|
out.writeBoolean(flush);
|
||||||
out.writeBoolean(refresh);
|
out.writeBoolean(refresh);
|
||||||
|
@ -161,6 +189,14 @@ public class IndicesStatsRequest extends BroadcastOperationRequest {
|
||||||
out.writeUTF(type);
|
out.writeUTF(type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (groups == null) {
|
||||||
|
out.writeVInt(0);
|
||||||
|
} else {
|
||||||
|
out.writeVInt(groups.length);
|
||||||
|
for (String group : groups) {
|
||||||
|
out.writeUTF(group);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void readFrom(StreamInput in) throws IOException {
|
@Override public void readFrom(StreamInput in) throws IOException {
|
||||||
|
@ -169,6 +205,7 @@ public class IndicesStatsRequest extends BroadcastOperationRequest {
|
||||||
store = in.readBoolean();
|
store = in.readBoolean();
|
||||||
indexing = in.readBoolean();
|
indexing = in.readBoolean();
|
||||||
get = in.readBoolean();
|
get = in.readBoolean();
|
||||||
|
search = in.readBoolean();
|
||||||
merge = in.readBoolean();
|
merge = in.readBoolean();
|
||||||
flush = in.readBoolean();
|
flush = in.readBoolean();
|
||||||
refresh = in.readBoolean();
|
refresh = in.readBoolean();
|
||||||
|
@ -179,5 +216,12 @@ public class IndicesStatsRequest extends BroadcastOperationRequest {
|
||||||
types[i] = in.readUTF();
|
types[i] = in.readUTF();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
size = in.readVInt();
|
||||||
|
if (size > 0) {
|
||||||
|
groups = new String[size];
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
groups[i] = in.readUTF();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -138,6 +138,9 @@ public class TransportIndicesStatsAction extends TransportBroadcastOperationActi
|
||||||
if (request.request.get()) {
|
if (request.request.get()) {
|
||||||
stats.stats.get = indexShard.getStats();
|
stats.stats.get = indexShard.getStats();
|
||||||
}
|
}
|
||||||
|
if (request.request.search()) {
|
||||||
|
stats.stats().search = indexShard.searchStats(request.request.groups());
|
||||||
|
}
|
||||||
if (request.request.merge()) {
|
if (request.request.merge()) {
|
||||||
stats.stats.merge = indexShard.mergeStats();
|
stats.stats.merge = indexShard.mergeStats();
|
||||||
}
|
}
|
||||||
|
|
|
@ -347,6 +347,10 @@ public class SearchRequest implements ActionRequest {
|
||||||
* Allows to provide additional source that will be used as well.
|
* Allows to provide additional source that will be used as well.
|
||||||
*/
|
*/
|
||||||
public SearchRequest extraSource(SearchSourceBuilder sourceBuilder) {
|
public SearchRequest extraSource(SearchSourceBuilder sourceBuilder) {
|
||||||
|
if (sourceBuilder == null) {
|
||||||
|
extraSource = null;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
BytesStream bos = sourceBuilder.buildAsUnsafeBytes(Requests.CONTENT_TYPE);
|
BytesStream bos = sourceBuilder.buildAsUnsafeBytes(Requests.CONTENT_TYPE);
|
||||||
this.extraSource = bos.underlyingBytes();
|
this.extraSource = bos.underlyingBytes();
|
||||||
this.extraSourceOffset = 0;
|
this.extraSourceOffset = 0;
|
||||||
|
|
|
@ -62,6 +62,11 @@ public class IndicesStatsRequestBuilder extends BaseIndicesRequestBuilder<Indice
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IndicesStatsRequestBuilder setGroups(String... groups) {
|
||||||
|
request.groups(groups);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public IndicesStatsRequestBuilder setDocs(boolean docs) {
|
public IndicesStatsRequestBuilder setDocs(boolean docs) {
|
||||||
request.docs(docs);
|
request.docs(docs);
|
||||||
return this;
|
return this;
|
||||||
|
@ -77,6 +82,16 @@ public class IndicesStatsRequestBuilder extends BaseIndicesRequestBuilder<Indice
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IndicesStatsRequestBuilder setGet(boolean get) {
|
||||||
|
request.get(get);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IndicesStatsRequestBuilder setSearch(boolean search) {
|
||||||
|
request.search(search);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public IndicesStatsRequestBuilder setMerge(boolean merge) {
|
public IndicesStatsRequestBuilder setMerge(boolean merge) {
|
||||||
request.merge(merge);
|
request.merge(merge);
|
||||||
return this;
|
return this;
|
||||||
|
|
|
@ -344,6 +344,14 @@ public class SearchRequestBuilder extends BaseRequestBuilder<SearchRequest, Sear
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The stats groups this request will be aggregated under.
|
||||||
|
*/
|
||||||
|
public SearchRequestBuilder setStats(String... statsGroups) {
|
||||||
|
sourceBuilder().stats(statsGroups);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets no fields to be loaded, resulting in only id and type to be returned per field.
|
* Sets no fields to be loaded, resulting in only id and type to be returned per field.
|
||||||
*/
|
*/
|
||||||
|
@ -491,7 +499,6 @@ public class SearchRequestBuilder extends BaseRequestBuilder<SearchRequest, Sear
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a field to be highlighted with a provided fragment size (in characters), and
|
* Adds a field to be highlighted with a provided fragment size (in characters), and
|
||||||
* default number of fragments of 5.
|
* default number of fragments of 5.
|
||||||
|
|
|
@ -179,16 +179,10 @@ public class IndexingStats implements Streamable, ToXContent {
|
||||||
return this.totalStats;
|
return this.totalStats;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, Stats> typeStats() {
|
@Nullable public Map<String, Stats> typeStats() {
|
||||||
return this.typeStats;
|
return this.typeStats;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IndexingStats readIndexingStats(StreamInput in) throws IOException {
|
|
||||||
IndexingStats indexingStats = new IndexingStats();
|
|
||||||
indexingStats.readFrom(in);
|
|
||||||
return indexingStats;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public XContentBuilder toXContent(XContentBuilder builder, ToXContent.Params params) throws IOException {
|
@Override public XContentBuilder toXContent(XContentBuilder builder, ToXContent.Params params) throws IOException {
|
||||||
builder.startObject(Fields.INDEXING);
|
builder.startObject(Fields.INDEXING);
|
||||||
totalStats.toXContent(builder, params);
|
totalStats.toXContent(builder, params);
|
||||||
|
@ -216,6 +210,12 @@ public class IndexingStats implements Streamable, ToXContent {
|
||||||
static final XContentBuilderString DELETE_TIME_IN_MILLIS = new XContentBuilderString("delete_time_in_millis");
|
static final XContentBuilderString DELETE_TIME_IN_MILLIS = new XContentBuilderString("delete_time_in_millis");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static IndexingStats readIndexingStats(StreamInput in) throws IOException {
|
||||||
|
IndexingStats indexingStats = new IndexingStats();
|
||||||
|
indexingStats.readFrom(in);
|
||||||
|
return indexingStats;
|
||||||
|
}
|
||||||
|
|
||||||
@Override public void readFrom(StreamInput in) throws IOException {
|
@Override public void readFrom(StreamInput in) throws IOException {
|
||||||
totalStats = Stats.readStats(in);
|
totalStats = Stats.readStats(in);
|
||||||
if (in.readBoolean()) {
|
if (in.readBoolean()) {
|
||||||
|
|
|
@ -0,0 +1,243 @@
|
||||||
|
/*
|
||||||
|
* 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.search.stats;
|
||||||
|
|
||||||
|
import org.elasticsearch.common.Nullable;
|
||||||
|
import org.elasticsearch.common.io.stream.StreamInput;
|
||||||
|
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||||
|
import org.elasticsearch.common.io.stream.Streamable;
|
||||||
|
import org.elasticsearch.common.unit.TimeValue;
|
||||||
|
import org.elasticsearch.common.xcontent.ToXContent;
|
||||||
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
|
import org.elasticsearch.common.xcontent.XContentBuilderString;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
public class SearchStats implements Streamable, ToXContent {
|
||||||
|
|
||||||
|
public static class Stats implements Streamable, ToXContent {
|
||||||
|
|
||||||
|
private long queryCount;
|
||||||
|
private long queryTimeInMillis;
|
||||||
|
|
||||||
|
private long fetchCount;
|
||||||
|
private long fetchTimeInMillis;
|
||||||
|
|
||||||
|
Stats() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Stats(long queryCount, long queryTimeInMillis, long fetchCount, long fetchTimeInMillis) {
|
||||||
|
this.queryCount = queryCount;
|
||||||
|
this.queryTimeInMillis = queryTimeInMillis;
|
||||||
|
this.fetchCount = fetchCount;
|
||||||
|
this.fetchTimeInMillis = fetchTimeInMillis;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(Stats stats) {
|
||||||
|
queryCount += stats.queryCount;
|
||||||
|
queryTimeInMillis += stats.queryTimeInMillis;
|
||||||
|
|
||||||
|
fetchCount += stats.fetchCount;
|
||||||
|
fetchTimeInMillis += stats.fetchTimeInMillis;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long queryCount() {
|
||||||
|
return queryCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getQueryCount() {
|
||||||
|
return queryCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TimeValue queryTime() {
|
||||||
|
return new TimeValue(queryTimeInMillis);
|
||||||
|
}
|
||||||
|
|
||||||
|
public long queryTimeInMillis() {
|
||||||
|
return queryTimeInMillis;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getQueryTimeInMillis() {
|
||||||
|
return queryTimeInMillis;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long fetchCount() {
|
||||||
|
return fetchCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getFetchCount() {
|
||||||
|
return fetchCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TimeValue fetchTime() {
|
||||||
|
return new TimeValue(fetchTimeInMillis);
|
||||||
|
}
|
||||||
|
|
||||||
|
public long fetchTimeInMillis() {
|
||||||
|
return fetchTimeInMillis;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getFetchTimeInMillis() {
|
||||||
|
return fetchTimeInMillis;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Stats readStats(StreamInput in) throws IOException {
|
||||||
|
Stats stats = new Stats();
|
||||||
|
stats.readFrom(in);
|
||||||
|
return stats;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public void readFrom(StreamInput in) throws IOException {
|
||||||
|
queryCount = in.readVLong();
|
||||||
|
queryTimeInMillis = in.readVLong();
|
||||||
|
|
||||||
|
fetchCount = in.readVLong();
|
||||||
|
fetchTimeInMillis = in.readVLong();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public void writeTo(StreamOutput out) throws IOException {
|
||||||
|
out.writeVLong(queryCount);
|
||||||
|
out.writeVLong(queryTimeInMillis);
|
||||||
|
|
||||||
|
out.writeVLong(fetchCount);
|
||||||
|
out.writeVLong(fetchTimeInMillis);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||||
|
builder.field(Fields.QUERY_TOTAL, queryCount);
|
||||||
|
builder.field(Fields.QUERY_TIME, queryTime().toString());
|
||||||
|
builder.field(Fields.QUERY_TIME_IN_MILLIS, queryTimeInMillis);
|
||||||
|
|
||||||
|
builder.field(Fields.FETCH_TOTAL, fetchCount);
|
||||||
|
builder.field(Fields.FETCH_TIME, fetchTime().toString());
|
||||||
|
builder.field(Fields.FETCH_TIME_IN_MILLIS, fetchTimeInMillis);
|
||||||
|
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Stats totalStats;
|
||||||
|
|
||||||
|
@Nullable Map<String, Stats> groupStats;
|
||||||
|
|
||||||
|
public SearchStats() {
|
||||||
|
totalStats = new Stats();
|
||||||
|
}
|
||||||
|
|
||||||
|
public SearchStats(Stats totalStats, @Nullable Map<String, Stats> groupStats) {
|
||||||
|
this.totalStats = totalStats;
|
||||||
|
this.groupStats = groupStats;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(SearchStats searchStats) {
|
||||||
|
add(searchStats, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(SearchStats searchStats, boolean includeTypes) {
|
||||||
|
if (searchStats == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
totalStats.add(searchStats.totalStats);
|
||||||
|
if (includeTypes && searchStats.groupStats != null && !searchStats.groupStats.isEmpty()) {
|
||||||
|
if (groupStats == null) {
|
||||||
|
groupStats = new HashMap<String, Stats>(searchStats.groupStats.size());
|
||||||
|
}
|
||||||
|
for (Map.Entry<String, Stats> entry : searchStats.groupStats.entrySet()) {
|
||||||
|
Stats stats = groupStats.get(entry.getKey());
|
||||||
|
if (stats == null) {
|
||||||
|
groupStats.put(entry.getKey(), entry.getValue());
|
||||||
|
} else {
|
||||||
|
stats.add(entry.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Stats total() {
|
||||||
|
return this.totalStats;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable public Map<String, Stats> groupStats() {
|
||||||
|
return this.groupStats;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public XContentBuilder toXContent(XContentBuilder builder, ToXContent.Params params) throws IOException {
|
||||||
|
builder.startObject(Fields.SEARCH);
|
||||||
|
totalStats.toXContent(builder, params);
|
||||||
|
if (groupStats != null && !groupStats.isEmpty()) {
|
||||||
|
builder.startObject(Fields.GROUPS);
|
||||||
|
for (Map.Entry<String, Stats> entry : groupStats.entrySet()) {
|
||||||
|
builder.startObject(entry.getKey(), XContentBuilder.FieldCaseConversion.NONE);
|
||||||
|
entry.getValue().toXContent(builder, params);
|
||||||
|
builder.endObject();
|
||||||
|
}
|
||||||
|
builder.endObject();
|
||||||
|
}
|
||||||
|
builder.endObject();
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
static final class Fields {
|
||||||
|
static final XContentBuilderString SEARCH = new XContentBuilderString("search");
|
||||||
|
static final XContentBuilderString GROUPS = new XContentBuilderString("groups");
|
||||||
|
static final XContentBuilderString QUERY_TOTAL = new XContentBuilderString("query_total");
|
||||||
|
static final XContentBuilderString QUERY_TIME = new XContentBuilderString("query_time");
|
||||||
|
static final XContentBuilderString QUERY_TIME_IN_MILLIS = new XContentBuilderString("query_time_in_millis");
|
||||||
|
static final XContentBuilderString FETCH_TOTAL = new XContentBuilderString("fetch_total");
|
||||||
|
static final XContentBuilderString FETCH_TIME = new XContentBuilderString("fetch_time");
|
||||||
|
static final XContentBuilderString FETCH_TIME_IN_MILLIS = new XContentBuilderString("fetch_time_in_millis");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SearchStats readSearchStats(StreamInput in) throws IOException {
|
||||||
|
SearchStats searchStats = new SearchStats();
|
||||||
|
searchStats.readFrom(in);
|
||||||
|
return searchStats;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public void readFrom(StreamInput in) throws IOException {
|
||||||
|
totalStats = Stats.readStats(in);
|
||||||
|
if (in.readBoolean()) {
|
||||||
|
int size = in.readVInt();
|
||||||
|
groupStats = new HashMap<String, Stats>(size);
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
groupStats.put(in.readUTF(), Stats.readStats(in));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public void writeTo(StreamOutput out) throws IOException {
|
||||||
|
totalStats.writeTo(out);
|
||||||
|
if (groupStats == null || groupStats.isEmpty()) {
|
||||||
|
out.writeBoolean(false);
|
||||||
|
} else {
|
||||||
|
out.writeBoolean(true);
|
||||||
|
out.writeVInt(groupStats.size());
|
||||||
|
for (Map.Entry<String, Stats> entry : groupStats.entrySet()) {
|
||||||
|
out.writeUTF(entry.getKey());
|
||||||
|
entry.getValue().writeTo(out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* 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.search.stats;
|
||||||
|
|
||||||
|
import org.elasticsearch.common.inject.AbstractModule;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
public class ShardSearchModule extends AbstractModule {
|
||||||
|
|
||||||
|
@Override protected void configure() {
|
||||||
|
bind(ShardSearchService.class).asEagerSingleton();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,129 @@
|
||||||
|
/*
|
||||||
|
* 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.search.stats;
|
||||||
|
|
||||||
|
import org.elasticsearch.common.collect.ImmutableMap;
|
||||||
|
import org.elasticsearch.common.collect.MapBuilder;
|
||||||
|
import org.elasticsearch.common.inject.Inject;
|
||||||
|
import org.elasticsearch.common.metrics.MeanMetric;
|
||||||
|
import org.elasticsearch.common.settings.Settings;
|
||||||
|
import org.elasticsearch.index.settings.IndexSettings;
|
||||||
|
import org.elasticsearch.index.shard.AbstractIndexShardComponent;
|
||||||
|
import org.elasticsearch.index.shard.ShardId;
|
||||||
|
import org.elasticsearch.search.internal.SearchContext;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
public class ShardSearchService extends AbstractIndexShardComponent {
|
||||||
|
|
||||||
|
private final StatsHolder totalStats = new StatsHolder();
|
||||||
|
|
||||||
|
private volatile Map<String, StatsHolder> groupsStats = ImmutableMap.of();
|
||||||
|
|
||||||
|
@Inject public ShardSearchService(ShardId shardId, @IndexSettings Settings indexSettings) {
|
||||||
|
super(shardId, indexSettings);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the stats, including group specific stats. If the groups are null/0 length, then nothing
|
||||||
|
* is returned for them. If they are set, then only groups provided will be returned, or
|
||||||
|
* <tt>_all</tt> for all groups.
|
||||||
|
*/
|
||||||
|
public SearchStats stats(String... groups) {
|
||||||
|
SearchStats.Stats total = totalStats.stats();
|
||||||
|
Map<String, SearchStats.Stats> groupsSt = null;
|
||||||
|
if (groups != null && groups.length > 0) {
|
||||||
|
if (groups.length == 1 && groups[0].equals("_all")) {
|
||||||
|
groupsSt = new HashMap<String, SearchStats.Stats>(groupsStats.size());
|
||||||
|
for (Map.Entry<String, StatsHolder> entry : groupsStats.entrySet()) {
|
||||||
|
groupsSt.put(entry.getKey(), entry.getValue().stats());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
groupsSt = new HashMap<String, SearchStats.Stats>(groups.length);
|
||||||
|
for (String group : groups) {
|
||||||
|
StatsHolder statsHolder = groupsStats.get(group);
|
||||||
|
if (statsHolder != null) {
|
||||||
|
groupsSt.put(group, statsHolder.stats());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new SearchStats(total, groupsSt);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onQueryPhase(SearchContext searchContext, long tookInNanos) {
|
||||||
|
totalStats.queryMetric.inc(tookInNanos);
|
||||||
|
if (searchContext.groupStats() != null) {
|
||||||
|
for (int i = 0; i < searchContext.groupStats().size(); i++) {
|
||||||
|
groupStats(searchContext.groupStats().get(i)).queryMetric.inc(tookInNanos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onFetchPhase(SearchContext searchContext, long tookInNanos) {
|
||||||
|
totalStats.fetchMetric.inc(tookInNanos);
|
||||||
|
if (searchContext.groupStats() != null) {
|
||||||
|
for (int i = 0; i < searchContext.groupStats().size(); i++) {
|
||||||
|
groupStats(searchContext.groupStats().get(i)).fetchMetric.inc(tookInNanos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
totalStats.clear();
|
||||||
|
synchronized (this) {
|
||||||
|
groupsStats = ImmutableMap.of();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private StatsHolder groupStats(String group) {
|
||||||
|
StatsHolder stats = groupsStats.get(group);
|
||||||
|
if (stats == null) {
|
||||||
|
synchronized (this) {
|
||||||
|
stats = groupsStats.get(group);
|
||||||
|
if (stats == null) {
|
||||||
|
stats = new StatsHolder();
|
||||||
|
groupsStats = MapBuilder.newMapBuilder(groupsStats).put(group, stats).immutableMap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return stats;
|
||||||
|
}
|
||||||
|
|
||||||
|
static class StatsHolder {
|
||||||
|
public final MeanMetric queryMetric = new MeanMetric();
|
||||||
|
public final MeanMetric fetchMetric = new MeanMetric();
|
||||||
|
|
||||||
|
public SearchStats.Stats stats() {
|
||||||
|
return new SearchStats.Stats(
|
||||||
|
queryMetric.count(), TimeUnit.NANOSECONDS.toMillis(queryMetric.sum()),
|
||||||
|
fetchMetric.count(), TimeUnit.NANOSECONDS.toMillis(fetchMetric.sum()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
queryMetric.clear();
|
||||||
|
fetchMetric.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
* 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.search.stats;
|
||||||
|
|
||||||
|
import org.elasticsearch.common.collect.ImmutableList;
|
||||||
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
|
import org.elasticsearch.search.SearchParseElement;
|
||||||
|
import org.elasticsearch.search.internal.SearchContext;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
public class StatsGroupsParseElement implements SearchParseElement {
|
||||||
|
|
||||||
|
@Override public void parse(XContentParser parser, SearchContext context) throws Exception {
|
||||||
|
XContentParser.Token token = parser.currentToken();
|
||||||
|
if (token.isValue()) {
|
||||||
|
context.groupStats(ImmutableList.of(parser.text()));
|
||||||
|
} else if (token == XContentParser.Token.START_ARRAY) {
|
||||||
|
List<String> groupStats = new ArrayList<String>(4);
|
||||||
|
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
|
||||||
|
groupStats.add(parser.text());
|
||||||
|
}
|
||||||
|
context.groupStats(groupStats);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -58,6 +58,7 @@ import org.elasticsearch.index.merge.policy.MergePolicyProvider;
|
||||||
import org.elasticsearch.index.merge.scheduler.MergeSchedulerModule;
|
import org.elasticsearch.index.merge.scheduler.MergeSchedulerModule;
|
||||||
import org.elasticsearch.index.percolator.PercolatorService;
|
import org.elasticsearch.index.percolator.PercolatorService;
|
||||||
import org.elasticsearch.index.query.IndexQueryParserService;
|
import org.elasticsearch.index.query.IndexQueryParserService;
|
||||||
|
import org.elasticsearch.index.search.stats.ShardSearchModule;
|
||||||
import org.elasticsearch.index.settings.IndexSettings;
|
import org.elasticsearch.index.settings.IndexSettings;
|
||||||
import org.elasticsearch.index.shard.IndexShardCreationException;
|
import org.elasticsearch.index.shard.IndexShardCreationException;
|
||||||
import org.elasticsearch.index.shard.IndexShardManagement;
|
import org.elasticsearch.index.shard.IndexShardManagement;
|
||||||
|
@ -282,6 +283,7 @@ public class InternalIndexService extends AbstractIndexComponent implements Inde
|
||||||
modules.add(new ShardsPluginsModule(indexSettings, pluginsService));
|
modules.add(new ShardsPluginsModule(indexSettings, pluginsService));
|
||||||
modules.add(new IndexShardModule(shardId));
|
modules.add(new IndexShardModule(shardId));
|
||||||
modules.add(new ShardIndexingModule());
|
modules.add(new ShardIndexingModule());
|
||||||
|
modules.add(new ShardSearchModule());
|
||||||
modules.add(new ShardGetModule());
|
modules.add(new ShardGetModule());
|
||||||
modules.add(new StoreModule(indexSettings, injector.getInstance(IndexStore.class)));
|
modules.add(new StoreModule(indexSettings, injector.getInstance(IndexStore.class)));
|
||||||
modules.add(new DeletionPolicyModule(indexSettings));
|
modules.add(new DeletionPolicyModule(indexSettings));
|
||||||
|
|
|
@ -34,6 +34,8 @@ import org.elasticsearch.index.mapper.ParsedDocument;
|
||||||
import org.elasticsearch.index.mapper.SourceToParse;
|
import org.elasticsearch.index.mapper.SourceToParse;
|
||||||
import org.elasticsearch.index.merge.MergeStats;
|
import org.elasticsearch.index.merge.MergeStats;
|
||||||
import org.elasticsearch.index.refresh.RefreshStats;
|
import org.elasticsearch.index.refresh.RefreshStats;
|
||||||
|
import org.elasticsearch.index.search.stats.SearchStats;
|
||||||
|
import org.elasticsearch.index.search.stats.ShardSearchService;
|
||||||
import org.elasticsearch.index.shard.DocsStats;
|
import org.elasticsearch.index.shard.DocsStats;
|
||||||
import org.elasticsearch.index.shard.IndexShardComponent;
|
import org.elasticsearch.index.shard.IndexShardComponent;
|
||||||
import org.elasticsearch.index.shard.IndexShardState;
|
import org.elasticsearch.index.shard.IndexShardState;
|
||||||
|
@ -49,6 +51,8 @@ public interface IndexShard extends IndexShardComponent {
|
||||||
|
|
||||||
ShardGetService getService();
|
ShardGetService getService();
|
||||||
|
|
||||||
|
ShardSearchService searchService();
|
||||||
|
|
||||||
ShardRouting routingEntry();
|
ShardRouting routingEntry();
|
||||||
|
|
||||||
DocsStats docStats();
|
DocsStats docStats();
|
||||||
|
@ -57,6 +61,8 @@ public interface IndexShard extends IndexShardComponent {
|
||||||
|
|
||||||
IndexingStats indexingStats(String... types);
|
IndexingStats indexingStats(String... types);
|
||||||
|
|
||||||
|
SearchStats searchStats(String... groups);
|
||||||
|
|
||||||
GetStats getStats();
|
GetStats getStats();
|
||||||
|
|
||||||
MergeStats mergeStats();
|
MergeStats mergeStats();
|
||||||
|
|
|
@ -60,6 +60,8 @@ import org.elasticsearch.index.merge.MergeStats;
|
||||||
import org.elasticsearch.index.merge.scheduler.MergeSchedulerProvider;
|
import org.elasticsearch.index.merge.scheduler.MergeSchedulerProvider;
|
||||||
import org.elasticsearch.index.query.IndexQueryParserService;
|
import org.elasticsearch.index.query.IndexQueryParserService;
|
||||||
import org.elasticsearch.index.refresh.RefreshStats;
|
import org.elasticsearch.index.refresh.RefreshStats;
|
||||||
|
import org.elasticsearch.index.search.stats.SearchStats;
|
||||||
|
import org.elasticsearch.index.search.stats.ShardSearchService;
|
||||||
import org.elasticsearch.index.settings.IndexSettings;
|
import org.elasticsearch.index.settings.IndexSettings;
|
||||||
import org.elasticsearch.index.settings.IndexSettingsService;
|
import org.elasticsearch.index.settings.IndexSettingsService;
|
||||||
import org.elasticsearch.index.shard.*;
|
import org.elasticsearch.index.shard.*;
|
||||||
|
@ -109,6 +111,8 @@ public class InternalIndexShard extends AbstractIndexShardComponent implements I
|
||||||
|
|
||||||
private final ShardIndexingService indexingService;
|
private final ShardIndexingService indexingService;
|
||||||
|
|
||||||
|
private final ShardSearchService searchService;
|
||||||
|
|
||||||
private final ShardGetService getService;
|
private final ShardGetService getService;
|
||||||
|
|
||||||
private final Object mutex = new Object();
|
private final Object mutex = new Object();
|
||||||
|
@ -135,7 +139,7 @@ public class InternalIndexShard extends AbstractIndexShardComponent implements I
|
||||||
private final MeanMetric flushMetric = new MeanMetric();
|
private final MeanMetric flushMetric = new MeanMetric();
|
||||||
|
|
||||||
@Inject public InternalIndexShard(ShardId shardId, @IndexSettings Settings indexSettings, IndexSettingsService indexSettingsService, IndicesLifecycle indicesLifecycle, Store store, Engine engine, MergeSchedulerProvider mergeScheduler, Translog translog,
|
@Inject public InternalIndexShard(ShardId shardId, @IndexSettings Settings indexSettings, IndexSettingsService indexSettingsService, IndicesLifecycle indicesLifecycle, Store store, Engine engine, MergeSchedulerProvider mergeScheduler, Translog translog,
|
||||||
ThreadPool threadPool, MapperService mapperService, IndexQueryParserService queryParserService, IndexCache indexCache, IndexAliasesService indexAliasesService, ShardIndexingService indexingService, ShardGetService getService) {
|
ThreadPool threadPool, MapperService mapperService, IndexQueryParserService queryParserService, IndexCache indexCache, IndexAliasesService indexAliasesService, ShardIndexingService indexingService, ShardGetService getService, ShardSearchService searchService) {
|
||||||
super(shardId, indexSettings);
|
super(shardId, indexSettings);
|
||||||
this.indicesLifecycle = (InternalIndicesLifecycle) indicesLifecycle;
|
this.indicesLifecycle = (InternalIndicesLifecycle) indicesLifecycle;
|
||||||
this.indexSettingsService = indexSettingsService;
|
this.indexSettingsService = indexSettingsService;
|
||||||
|
@ -150,6 +154,7 @@ public class InternalIndexShard extends AbstractIndexShardComponent implements I
|
||||||
this.indexAliasesService = indexAliasesService;
|
this.indexAliasesService = indexAliasesService;
|
||||||
this.indexingService = indexingService;
|
this.indexingService = indexingService;
|
||||||
this.getService = getService.setIndexShard(this);
|
this.getService = getService.setIndexShard(this);
|
||||||
|
this.searchService = searchService;
|
||||||
state = IndexShardState.CREATED;
|
state = IndexShardState.CREATED;
|
||||||
|
|
||||||
this.refreshInterval = indexSettings.getAsTime("engine.robin.refresh_interval", indexSettings.getAsTime("index.refresh_interval", engine.defaultRefreshInterval()));
|
this.refreshInterval = indexSettings.getAsTime("engine.robin.refresh_interval", indexSettings.getAsTime("index.refresh_interval", engine.defaultRefreshInterval()));
|
||||||
|
@ -186,6 +191,10 @@ public class InternalIndexShard extends AbstractIndexShardComponent implements I
|
||||||
return this.getService;
|
return this.getService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override public ShardSearchService searchService() {
|
||||||
|
return this.searchService;
|
||||||
|
}
|
||||||
|
|
||||||
@Override public ShardRouting routingEntry() {
|
@Override public ShardRouting routingEntry() {
|
||||||
return this.shardRouting;
|
return this.shardRouting;
|
||||||
}
|
}
|
||||||
|
@ -413,6 +422,10 @@ public class InternalIndexShard extends AbstractIndexShardComponent implements I
|
||||||
return indexingService.stats(types);
|
return indexingService.stats(types);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override public SearchStats searchStats(String... groups) {
|
||||||
|
return searchService.stats(groups);
|
||||||
|
}
|
||||||
|
|
||||||
@Override public GetStats getStats() {
|
@Override public GetStats getStats() {
|
||||||
return getService.stats();
|
return getService.stats();
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,6 +64,7 @@ import org.elasticsearch.index.percolator.PercolatorService;
|
||||||
import org.elasticsearch.index.query.IndexQueryParserModule;
|
import org.elasticsearch.index.query.IndexQueryParserModule;
|
||||||
import org.elasticsearch.index.query.IndexQueryParserService;
|
import org.elasticsearch.index.query.IndexQueryParserService;
|
||||||
import org.elasticsearch.index.refresh.RefreshStats;
|
import org.elasticsearch.index.refresh.RefreshStats;
|
||||||
|
import org.elasticsearch.index.search.stats.SearchStats;
|
||||||
import org.elasticsearch.index.service.IndexService;
|
import org.elasticsearch.index.service.IndexService;
|
||||||
import org.elasticsearch.index.service.InternalIndexService;
|
import org.elasticsearch.index.service.InternalIndexService;
|
||||||
import org.elasticsearch.index.settings.IndexSettingsModule;
|
import org.elasticsearch.index.settings.IndexSettingsModule;
|
||||||
|
@ -180,6 +181,7 @@ public class InternalIndicesService extends AbstractLifecycleComponent<IndicesSe
|
||||||
StoreStats storeStats = new StoreStats();
|
StoreStats storeStats = new StoreStats();
|
||||||
IndexingStats indexingStats = new IndexingStats();
|
IndexingStats indexingStats = new IndexingStats();
|
||||||
GetStats getStats = new GetStats();
|
GetStats getStats = new GetStats();
|
||||||
|
SearchStats searchStats = new SearchStats();
|
||||||
CacheStats cacheStats = new CacheStats();
|
CacheStats cacheStats = new CacheStats();
|
||||||
MergeStats mergeStats = new MergeStats();
|
MergeStats mergeStats = new MergeStats();
|
||||||
RefreshStats refreshStats = new RefreshStats();
|
RefreshStats refreshStats = new RefreshStats();
|
||||||
|
@ -188,6 +190,7 @@ public class InternalIndicesService extends AbstractLifecycleComponent<IndicesSe
|
||||||
if (includePrevious) {
|
if (includePrevious) {
|
||||||
getStats.add(oldShardsStats.getStats);
|
getStats.add(oldShardsStats.getStats);
|
||||||
indexingStats.add(oldShardsStats.indexingStats);
|
indexingStats.add(oldShardsStats.indexingStats);
|
||||||
|
searchStats.add(oldShardsStats.searchStats);
|
||||||
mergeStats.add(oldShardsStats.mergeStats);
|
mergeStats.add(oldShardsStats.mergeStats);
|
||||||
refreshStats.add(oldShardsStats.refreshStats);
|
refreshStats.add(oldShardsStats.refreshStats);
|
||||||
flushStats.add(oldShardsStats.flushStats);
|
flushStats.add(oldShardsStats.flushStats);
|
||||||
|
@ -199,13 +202,14 @@ public class InternalIndicesService extends AbstractLifecycleComponent<IndicesSe
|
||||||
docsStats.add(indexShard.docStats());
|
docsStats.add(indexShard.docStats());
|
||||||
getStats.add(indexShard.getStats());
|
getStats.add(indexShard.getStats());
|
||||||
indexingStats.add(indexShard.indexingStats());
|
indexingStats.add(indexShard.indexingStats());
|
||||||
|
searchStats.add(indexShard.searchStats());
|
||||||
mergeStats.add(indexShard.mergeStats());
|
mergeStats.add(indexShard.mergeStats());
|
||||||
refreshStats.add(indexShard.refreshStats());
|
refreshStats.add(indexShard.refreshStats());
|
||||||
flushStats.add(indexShard.flushStats());
|
flushStats.add(indexShard.flushStats());
|
||||||
}
|
}
|
||||||
cacheStats.add(indexService.cache().stats());
|
cacheStats.add(indexService.cache().stats());
|
||||||
}
|
}
|
||||||
return new NodeIndicesStats(storeStats, docsStats, indexingStats, cacheStats, mergeStats, refreshStats, flushStats);
|
return new NodeIndicesStats(storeStats, docsStats, indexingStats, getStats, searchStats, cacheStats, mergeStats, refreshStats, flushStats);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -352,6 +356,7 @@ public class InternalIndicesService extends AbstractLifecycleComponent<IndicesSe
|
||||||
|
|
||||||
static class OldShardsStats extends IndicesLifecycle.Listener {
|
static class OldShardsStats extends IndicesLifecycle.Listener {
|
||||||
|
|
||||||
|
final SearchStats searchStats = new SearchStats();
|
||||||
final GetStats getStats = new GetStats();
|
final GetStats getStats = new GetStats();
|
||||||
final IndexingStats indexingStats = new IndexingStats();
|
final IndexingStats indexingStats = new IndexingStats();
|
||||||
final MergeStats mergeStats = new MergeStats();
|
final MergeStats mergeStats = new MergeStats();
|
||||||
|
@ -362,6 +367,7 @@ public class InternalIndicesService extends AbstractLifecycleComponent<IndicesSe
|
||||||
if (indexShard != null) {
|
if (indexShard != null) {
|
||||||
getStats.add(indexShard.getStats());
|
getStats.add(indexShard.getStats());
|
||||||
indexingStats.add(indexShard.indexingStats(), false);
|
indexingStats.add(indexShard.indexingStats(), false);
|
||||||
|
searchStats.add(indexShard.searchStats(), false);
|
||||||
mergeStats.add(indexShard.mergeStats());
|
mergeStats.add(indexShard.mergeStats());
|
||||||
refreshStats.add(indexShard.refreshStats());
|
refreshStats.add(indexShard.refreshStats());
|
||||||
flushStats.add(indexShard.flushStats());
|
flushStats.add(indexShard.flushStats());
|
||||||
|
|
|
@ -27,9 +27,11 @@ import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilderString;
|
import org.elasticsearch.common.xcontent.XContentBuilderString;
|
||||||
import org.elasticsearch.index.cache.CacheStats;
|
import org.elasticsearch.index.cache.CacheStats;
|
||||||
import org.elasticsearch.index.flush.FlushStats;
|
import org.elasticsearch.index.flush.FlushStats;
|
||||||
|
import org.elasticsearch.index.get.GetStats;
|
||||||
import org.elasticsearch.index.indexing.IndexingStats;
|
import org.elasticsearch.index.indexing.IndexingStats;
|
||||||
import org.elasticsearch.index.merge.MergeStats;
|
import org.elasticsearch.index.merge.MergeStats;
|
||||||
import org.elasticsearch.index.refresh.RefreshStats;
|
import org.elasticsearch.index.refresh.RefreshStats;
|
||||||
|
import org.elasticsearch.index.search.stats.SearchStats;
|
||||||
import org.elasticsearch.index.shard.DocsStats;
|
import org.elasticsearch.index.shard.DocsStats;
|
||||||
import org.elasticsearch.index.store.StoreStats;
|
import org.elasticsearch.index.store.StoreStats;
|
||||||
|
|
||||||
|
@ -49,6 +51,10 @@ public class NodeIndicesStats implements Streamable, Serializable, ToXContent {
|
||||||
|
|
||||||
private IndexingStats indexingStats;
|
private IndexingStats indexingStats;
|
||||||
|
|
||||||
|
private GetStats getStats;
|
||||||
|
|
||||||
|
private SearchStats searchStats;
|
||||||
|
|
||||||
private CacheStats cacheStats;
|
private CacheStats cacheStats;
|
||||||
|
|
||||||
private MergeStats mergeStats;
|
private MergeStats mergeStats;
|
||||||
|
@ -60,10 +66,12 @@ public class NodeIndicesStats implements Streamable, Serializable, ToXContent {
|
||||||
NodeIndicesStats() {
|
NodeIndicesStats() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public NodeIndicesStats(StoreStats storeStats, DocsStats docsStats, IndexingStats indexingStats, CacheStats cacheStats, MergeStats mergeStats, RefreshStats refreshStats, FlushStats flushStats) {
|
public NodeIndicesStats(StoreStats storeStats, DocsStats docsStats, IndexingStats indexingStats, GetStats getStats, SearchStats searchStats, CacheStats cacheStats, MergeStats mergeStats, RefreshStats refreshStats, FlushStats flushStats) {
|
||||||
this.storeStats = storeStats;
|
this.storeStats = storeStats;
|
||||||
this.docsStats = docsStats;
|
this.docsStats = docsStats;
|
||||||
this.indexingStats = indexingStats;
|
this.indexingStats = indexingStats;
|
||||||
|
this.getStats = getStats;
|
||||||
|
this.searchStats = searchStats;
|
||||||
this.cacheStats = cacheStats;
|
this.cacheStats = cacheStats;
|
||||||
this.mergeStats = mergeStats;
|
this.mergeStats = mergeStats;
|
||||||
this.refreshStats = refreshStats;
|
this.refreshStats = refreshStats;
|
||||||
|
@ -97,6 +105,22 @@ public class NodeIndicesStats implements Streamable, Serializable, ToXContent {
|
||||||
return indexing();
|
return indexing();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public GetStats get() {
|
||||||
|
return this.getStats;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GetStats getGet() {
|
||||||
|
return this.getStats;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SearchStats search() {
|
||||||
|
return this.searchStats;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SearchStats getSearch() {
|
||||||
|
return this.searchStats;
|
||||||
|
}
|
||||||
|
|
||||||
public CacheStats cache() {
|
public CacheStats cache() {
|
||||||
return this.cacheStats;
|
return this.cacheStats;
|
||||||
}
|
}
|
||||||
|
@ -139,6 +163,8 @@ public class NodeIndicesStats implements Streamable, Serializable, ToXContent {
|
||||||
storeStats = StoreStats.readStoreStats(in);
|
storeStats = StoreStats.readStoreStats(in);
|
||||||
docsStats = DocsStats.readDocStats(in);
|
docsStats = DocsStats.readDocStats(in);
|
||||||
indexingStats = IndexingStats.readIndexingStats(in);
|
indexingStats = IndexingStats.readIndexingStats(in);
|
||||||
|
getStats = GetStats.readGetStats(in);
|
||||||
|
searchStats = SearchStats.readSearchStats(in);
|
||||||
cacheStats = CacheStats.readCacheStats(in);
|
cacheStats = CacheStats.readCacheStats(in);
|
||||||
mergeStats = MergeStats.readMergeStats(in);
|
mergeStats = MergeStats.readMergeStats(in);
|
||||||
refreshStats = RefreshStats.readRefreshStats(in);
|
refreshStats = RefreshStats.readRefreshStats(in);
|
||||||
|
@ -149,6 +175,8 @@ public class NodeIndicesStats implements Streamable, Serializable, ToXContent {
|
||||||
storeStats.writeTo(out);
|
storeStats.writeTo(out);
|
||||||
docsStats.writeTo(out);
|
docsStats.writeTo(out);
|
||||||
indexingStats.writeTo(out);
|
indexingStats.writeTo(out);
|
||||||
|
getStats.writeTo(out);
|
||||||
|
searchStats.writeTo(out);
|
||||||
cacheStats.writeTo(out);
|
cacheStats.writeTo(out);
|
||||||
mergeStats.writeTo(out);
|
mergeStats.writeTo(out);
|
||||||
refreshStats.writeTo(out);
|
refreshStats.writeTo(out);
|
||||||
|
@ -161,6 +189,8 @@ public class NodeIndicesStats implements Streamable, Serializable, ToXContent {
|
||||||
storeStats.toXContent(builder, params);
|
storeStats.toXContent(builder, params);
|
||||||
docsStats.toXContent(builder, params);
|
docsStats.toXContent(builder, params);
|
||||||
indexingStats.toXContent(builder, params);
|
indexingStats.toXContent(builder, params);
|
||||||
|
getStats.toXContent(builder, params);
|
||||||
|
searchStats.toXContent(builder, params);
|
||||||
cacheStats.toXContent(builder, params);
|
cacheStats.toXContent(builder, params);
|
||||||
mergeStats.toXContent(builder, params);
|
mergeStats.toXContent(builder, params);
|
||||||
refreshStats.toXContent(builder, params);
|
refreshStats.toXContent(builder, params);
|
||||||
|
|
|
@ -23,6 +23,7 @@ import org.elasticsearch.action.ActionListener;
|
||||||
import org.elasticsearch.action.admin.indices.stats.IndicesStats;
|
import org.elasticsearch.action.admin.indices.stats.IndicesStats;
|
||||||
import org.elasticsearch.action.admin.indices.stats.IndicesStatsRequest;
|
import org.elasticsearch.action.admin.indices.stats.IndicesStatsRequest;
|
||||||
import org.elasticsearch.client.Client;
|
import org.elasticsearch.client.Client;
|
||||||
|
import org.elasticsearch.common.Strings;
|
||||||
import org.elasticsearch.common.inject.Inject;
|
import org.elasticsearch.common.inject.Inject;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
|
@ -49,20 +50,32 @@ public class RestIndicesStatsAction extends BaseRestHandler {
|
||||||
super(settings, client);
|
super(settings, client);
|
||||||
controller.registerHandler(GET, "/_stats", this);
|
controller.registerHandler(GET, "/_stats", this);
|
||||||
controller.registerHandler(GET, "/{index}/_stats", this);
|
controller.registerHandler(GET, "/{index}/_stats", this);
|
||||||
|
|
||||||
controller.registerHandler(GET, "_stats/docs", new RestDocsStatsHandler());
|
controller.registerHandler(GET, "_stats/docs", new RestDocsStatsHandler());
|
||||||
controller.registerHandler(GET, "/{index}/_stats/docs", new RestDocsStatsHandler());
|
controller.registerHandler(GET, "/{index}/_stats/docs", new RestDocsStatsHandler());
|
||||||
|
|
||||||
controller.registerHandler(GET, "/_stats/store", new RestStoreStatsHandler());
|
controller.registerHandler(GET, "/_stats/store", new RestStoreStatsHandler());
|
||||||
controller.registerHandler(GET, "/{index}/_stats/store", new RestStoreStatsHandler());
|
controller.registerHandler(GET, "/{index}/_stats/store", new RestStoreStatsHandler());
|
||||||
|
|
||||||
controller.registerHandler(GET, "/_stats/indexing", new RestIndexingStatsHandler());
|
controller.registerHandler(GET, "/_stats/indexing", new RestIndexingStatsHandler());
|
||||||
controller.registerHandler(GET, "/{index}/_stats/indexing", new RestIndexingStatsHandler());
|
controller.registerHandler(GET, "/{index}/_stats/indexing", new RestIndexingStatsHandler());
|
||||||
|
controller.registerHandler(GET, "/_stats/indexing/{indexingTypes1}", new RestIndexingStatsHandler());
|
||||||
|
controller.registerHandler(GET, "/{index}/_stats/indexing/{indexingTypes2}", new RestIndexingStatsHandler());
|
||||||
|
|
||||||
|
controller.registerHandler(GET, "/_stats/search", new RestSearchStatsHandler());
|
||||||
|
controller.registerHandler(GET, "/{index}/_stats/search", new RestSearchStatsHandler());
|
||||||
|
controller.registerHandler(GET, "/_stats/search/{searchGroupsStats1}", new RestSearchStatsHandler());
|
||||||
|
controller.registerHandler(GET, "/{index}/_stats/search/{searchGroupsStats2}", new RestSearchStatsHandler());
|
||||||
|
|
||||||
controller.registerHandler(GET, "/_stats/get", new RestGetStatsHandler());
|
controller.registerHandler(GET, "/_stats/get", new RestGetStatsHandler());
|
||||||
controller.registerHandler(GET, "/{index}/_stats/get", new RestGetStatsHandler());
|
controller.registerHandler(GET, "/{index}/_stats/get", new RestGetStatsHandler());
|
||||||
controller.registerHandler(GET, "/_stats/indexing/{indexingTypes}", new RestIndexingStatsHandler());
|
|
||||||
controller.registerHandler(GET, "/{index}/_stats/indexing/{indexingTypes}", new RestIndexingStatsHandler());
|
|
||||||
controller.registerHandler(GET, "/_stats/refresh", new RestRefreshStatsHandler());
|
controller.registerHandler(GET, "/_stats/refresh", new RestRefreshStatsHandler());
|
||||||
controller.registerHandler(GET, "/{index}/_stats/refresh", new RestRefreshStatsHandler());
|
controller.registerHandler(GET, "/{index}/_stats/refresh", new RestRefreshStatsHandler());
|
||||||
|
|
||||||
controller.registerHandler(GET, "/_stats/merge", new RestMergeStatsHandler());
|
controller.registerHandler(GET, "/_stats/merge", new RestMergeStatsHandler());
|
||||||
controller.registerHandler(GET, "/{index}/_stats/merge", new RestMergeStatsHandler());
|
controller.registerHandler(GET, "/{index}/_stats/merge", new RestMergeStatsHandler());
|
||||||
|
|
||||||
controller.registerHandler(GET, "/_stats/flush", new RestFlushStatsHandler());
|
controller.registerHandler(GET, "/_stats/flush", new RestFlushStatsHandler());
|
||||||
controller.registerHandler(GET, "/{index}/_stats/flush", new RestFlushStatsHandler());
|
controller.registerHandler(GET, "/{index}/_stats/flush", new RestFlushStatsHandler());
|
||||||
}
|
}
|
||||||
|
@ -75,6 +88,9 @@ public class RestIndicesStatsAction extends BaseRestHandler {
|
||||||
if (clear) {
|
if (clear) {
|
||||||
indicesStatsRequest.clear();
|
indicesStatsRequest.clear();
|
||||||
}
|
}
|
||||||
|
if (request.hasParam("groups")) {
|
||||||
|
indicesStatsRequest.groups(Strings.splitStringByCommaToArray(request.param("groups")));
|
||||||
|
}
|
||||||
indicesStatsRequest.docs(request.paramAsBoolean("docs", indicesStatsRequest.docs()));
|
indicesStatsRequest.docs(request.paramAsBoolean("docs", indicesStatsRequest.docs()));
|
||||||
indicesStatsRequest.store(request.paramAsBoolean("store", indicesStatsRequest.store()));
|
indicesStatsRequest.store(request.paramAsBoolean("store", indicesStatsRequest.store()));
|
||||||
indicesStatsRequest.indexing(request.paramAsBoolean("indexing", indicesStatsRequest.indexing()));
|
indicesStatsRequest.indexing(request.paramAsBoolean("indexing", indicesStatsRequest.indexing()));
|
||||||
|
@ -181,10 +197,12 @@ public class RestIndicesStatsAction extends BaseRestHandler {
|
||||||
@Override public void handleRequest(final RestRequest request, final RestChannel channel) {
|
@Override public void handleRequest(final RestRequest request, final RestChannel channel) {
|
||||||
IndicesStatsRequest indicesStatsRequest = new IndicesStatsRequest();
|
IndicesStatsRequest indicesStatsRequest = new IndicesStatsRequest();
|
||||||
indicesStatsRequest.indices(splitIndices(request.param("index")));
|
indicesStatsRequest.indices(splitIndices(request.param("index")));
|
||||||
if (request.param("types") != null) {
|
if (request.hasParam("types")) {
|
||||||
indicesStatsRequest.types(splitTypes(request.param("types")));
|
indicesStatsRequest.types(splitTypes(request.param("types")));
|
||||||
} else {
|
} else if (request.hasParam("indexingTypes1")) {
|
||||||
indicesStatsRequest.types(splitTypes(request.param("indexingTypes")));
|
indicesStatsRequest.types(splitTypes(request.param("indexingTypes1")));
|
||||||
|
} else if (request.hasParam("indexingTypes2")) {
|
||||||
|
indicesStatsRequest.types(splitTypes(request.param("indexingTypes2")));
|
||||||
}
|
}
|
||||||
indicesStatsRequest.clear().indexing(true);
|
indicesStatsRequest.clear().indexing(true);
|
||||||
|
|
||||||
|
@ -214,6 +232,46 @@ public class RestIndicesStatsAction extends BaseRestHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class RestSearchStatsHandler implements RestHandler {
|
||||||
|
|
||||||
|
@Override public void handleRequest(final RestRequest request, final RestChannel channel) {
|
||||||
|
IndicesStatsRequest indicesStatsRequest = new IndicesStatsRequest();
|
||||||
|
indicesStatsRequest.indices(splitIndices(request.param("index")));
|
||||||
|
if (request.hasParam("groups")) {
|
||||||
|
indicesStatsRequest.groups(Strings.splitStringByCommaToArray(request.param("groups")));
|
||||||
|
} else if (request.hasParam("searchGroupsStats1")) {
|
||||||
|
indicesStatsRequest.groups(Strings.splitStringByCommaToArray(request.param("searchGroupsStats1")));
|
||||||
|
} else if (request.hasParam("searchGroupsStats2")) {
|
||||||
|
indicesStatsRequest.groups(Strings.splitStringByCommaToArray(request.param("searchGroupsStats2")));
|
||||||
|
}
|
||||||
|
indicesStatsRequest.clear().search(true);
|
||||||
|
|
||||||
|
client.admin().indices().stats(indicesStatsRequest, new ActionListener<IndicesStats>() {
|
||||||
|
@Override public void onResponse(IndicesStats response) {
|
||||||
|
try {
|
||||||
|
XContentBuilder builder = RestXContentBuilder.restContentBuilder(request);
|
||||||
|
builder.startObject();
|
||||||
|
builder.field("ok", true);
|
||||||
|
buildBroadcastShardsHeader(builder, response);
|
||||||
|
response.toXContent(builder, request);
|
||||||
|
builder.endObject();
|
||||||
|
channel.sendResponse(new XContentRestResponse(request, OK, builder));
|
||||||
|
} catch (Exception e) {
|
||||||
|
onFailure(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public void onFailure(Throwable e) {
|
||||||
|
try {
|
||||||
|
channel.sendResponse(new XContentThrowableRestResponse(request, e));
|
||||||
|
} catch (IOException e1) {
|
||||||
|
logger.error("Failed to send failure response", e1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class RestGetStatsHandler implements RestHandler {
|
class RestGetStatsHandler implements RestHandler {
|
||||||
|
|
||||||
@Override public void handleRequest(final RestRequest request, final RestChannel channel) {
|
@Override public void handleRequest(final RestRequest request, final RestChannel channel) {
|
||||||
|
|
|
@ -147,7 +147,7 @@ public class RestSearchAction extends BaseRestHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
private SearchSourceBuilder parseSearchSource(RestRequest request) {
|
private SearchSourceBuilder parseSearchSource(RestRequest request) {
|
||||||
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
|
SearchSourceBuilder searchSourceBuilder = null;
|
||||||
String queryString = request.param("q");
|
String queryString = request.param("q");
|
||||||
if (queryString != null) {
|
if (queryString != null) {
|
||||||
QueryStringQueryBuilder queryBuilder = QueryBuilders.queryString(queryString);
|
QueryStringQueryBuilder queryBuilder = QueryBuilders.queryString(queryString);
|
||||||
|
@ -165,24 +165,45 @@ public class RestSearchAction extends BaseRestHandler {
|
||||||
throw new ElasticSearchIllegalArgumentException("Unsupported defaultOperator [" + defaultOperator + "], can either be [OR] or [AND]");
|
throw new ElasticSearchIllegalArgumentException("Unsupported defaultOperator [" + defaultOperator + "], can either be [OR] or [AND]");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (searchSourceBuilder == null) {
|
||||||
|
searchSourceBuilder = new SearchSourceBuilder();
|
||||||
|
}
|
||||||
searchSourceBuilder.query(queryBuilder);
|
searchSourceBuilder.query(queryBuilder);
|
||||||
}
|
}
|
||||||
|
|
||||||
int from = request.paramAsInt("from", -1);
|
int from = request.paramAsInt("from", -1);
|
||||||
if (from != -1) {
|
if (from != -1) {
|
||||||
|
if (searchSourceBuilder == null) {
|
||||||
|
searchSourceBuilder = new SearchSourceBuilder();
|
||||||
|
}
|
||||||
searchSourceBuilder.from(from);
|
searchSourceBuilder.from(from);
|
||||||
}
|
}
|
||||||
int size = request.paramAsInt("size", -1);
|
int size = request.paramAsInt("size", -1);
|
||||||
if (size != -1) {
|
if (size != -1) {
|
||||||
|
if (searchSourceBuilder == null) {
|
||||||
|
searchSourceBuilder = new SearchSourceBuilder();
|
||||||
|
}
|
||||||
searchSourceBuilder.size(size);
|
searchSourceBuilder.size(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (request.hasParam("explain")) {
|
||||||
searchSourceBuilder.explain(request.paramAsBooleanOptional("explain", null));
|
if (searchSourceBuilder == null) {
|
||||||
searchSourceBuilder.version(request.paramAsBooleanOptional("version", null));
|
searchSourceBuilder = new SearchSourceBuilder();
|
||||||
|
}
|
||||||
|
searchSourceBuilder.explain(request.paramAsBooleanOptional("explain", null));
|
||||||
|
}
|
||||||
|
if (request.hasParam("version")) {
|
||||||
|
if (searchSourceBuilder == null) {
|
||||||
|
searchSourceBuilder = new SearchSourceBuilder();
|
||||||
|
}
|
||||||
|
searchSourceBuilder.version(request.paramAsBooleanOptional("version", null));
|
||||||
|
}
|
||||||
|
|
||||||
String sField = request.param("fields");
|
String sField = request.param("fields");
|
||||||
if (sField != null) {
|
if (sField != null) {
|
||||||
|
if (searchSourceBuilder == null) {
|
||||||
|
searchSourceBuilder = new SearchSourceBuilder();
|
||||||
|
}
|
||||||
if (!Strings.hasText(sField)) {
|
if (!Strings.hasText(sField)) {
|
||||||
searchSourceBuilder.noFields();
|
searchSourceBuilder.noFields();
|
||||||
} else {
|
} else {
|
||||||
|
@ -197,6 +218,9 @@ public class RestSearchAction extends BaseRestHandler {
|
||||||
|
|
||||||
String sSorts = request.param("sort");
|
String sSorts = request.param("sort");
|
||||||
if (sSorts != null) {
|
if (sSorts != null) {
|
||||||
|
if (searchSourceBuilder == null) {
|
||||||
|
searchSourceBuilder = new SearchSourceBuilder();
|
||||||
|
}
|
||||||
String[] sorts = Strings.splitStringByCommaToArray(sSorts);
|
String[] sorts = Strings.splitStringByCommaToArray(sSorts);
|
||||||
for (String sort : sorts) {
|
for (String sort : sorts) {
|
||||||
int delimiter = sort.lastIndexOf(":");
|
int delimiter = sort.lastIndexOf(":");
|
||||||
|
@ -216,6 +240,9 @@ public class RestSearchAction extends BaseRestHandler {
|
||||||
|
|
||||||
String sIndicesBoost = request.param("indices_boost");
|
String sIndicesBoost = request.param("indices_boost");
|
||||||
if (sIndicesBoost != null) {
|
if (sIndicesBoost != null) {
|
||||||
|
if (searchSourceBuilder == null) {
|
||||||
|
searchSourceBuilder = new SearchSourceBuilder();
|
||||||
|
}
|
||||||
String[] indicesBoost = Strings.splitStringByCommaToArray(sIndicesBoost);
|
String[] indicesBoost = Strings.splitStringByCommaToArray(sIndicesBoost);
|
||||||
for (String indexBoost : indicesBoost) {
|
for (String indexBoost : indicesBoost) {
|
||||||
int divisor = indexBoost.indexOf(',');
|
int divisor = indexBoost.indexOf(',');
|
||||||
|
@ -232,6 +259,14 @@ public class RestSearchAction extends BaseRestHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String sStats = request.param("stats");
|
||||||
|
if (sStats != null) {
|
||||||
|
if (searchSourceBuilder == null) {
|
||||||
|
searchSourceBuilder = new SearchSourceBuilder();
|
||||||
|
}
|
||||||
|
searchSourceBuilder.stats(Strings.splitStringByCommaToArray(sStats));
|
||||||
|
}
|
||||||
|
|
||||||
return searchSourceBuilder;
|
return searchSourceBuilder;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,7 @@ import org.elasticsearch.common.xcontent.XContentFactory;
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
import org.elasticsearch.index.Index;
|
import org.elasticsearch.index.Index;
|
||||||
import org.elasticsearch.index.engine.Engine;
|
import org.elasticsearch.index.engine.Engine;
|
||||||
|
import org.elasticsearch.index.search.stats.StatsGroupsParseElement;
|
||||||
import org.elasticsearch.index.service.IndexService;
|
import org.elasticsearch.index.service.IndexService;
|
||||||
import org.elasticsearch.index.shard.ShardId;
|
import org.elasticsearch.index.shard.ShardId;
|
||||||
import org.elasticsearch.index.shard.service.IndexShard;
|
import org.elasticsearch.index.shard.service.IndexShard;
|
||||||
|
@ -121,6 +122,7 @@ public class SearchService extends AbstractLifecycleComponent<SearchService> {
|
||||||
elementParsers.putAll(dfsPhase.parseElements());
|
elementParsers.putAll(dfsPhase.parseElements());
|
||||||
elementParsers.putAll(queryPhase.parseElements());
|
elementParsers.putAll(queryPhase.parseElements());
|
||||||
elementParsers.putAll(fetchPhase.parseElements());
|
elementParsers.putAll(fetchPhase.parseElements());
|
||||||
|
elementParsers.put("stats", new StatsGroupsParseElement());
|
||||||
this.elementParsers = ImmutableMap.copyOf(elementParsers);
|
this.elementParsers = ImmutableMap.copyOf(elementParsers);
|
||||||
indicesLifecycle.addListener(indicesLifecycleListener);
|
indicesLifecycle.addListener(indicesLifecycleListener);
|
||||||
|
|
||||||
|
@ -230,6 +232,7 @@ public class SearchService extends AbstractLifecycleComponent<SearchService> {
|
||||||
SearchContext context = createContext(request);
|
SearchContext context = createContext(request);
|
||||||
activeContexts.put(context.id(), context);
|
activeContexts.put(context.id(), context);
|
||||||
try {
|
try {
|
||||||
|
long time = System.nanoTime();
|
||||||
contextProcessing(context);
|
contextProcessing(context);
|
||||||
queryPhase.execute(context);
|
queryPhase.execute(context);
|
||||||
if (context.searchType() == SearchType.COUNT) {
|
if (context.searchType() == SearchType.COUNT) {
|
||||||
|
@ -237,6 +240,7 @@ public class SearchService extends AbstractLifecycleComponent<SearchService> {
|
||||||
} else {
|
} else {
|
||||||
contextProcessedSuccessfully(context);
|
contextProcessedSuccessfully(context);
|
||||||
}
|
}
|
||||||
|
context.indexShard().searchService().onQueryPhase(context, System.nanoTime() - time);
|
||||||
return context.queryResult();
|
return context.queryResult();
|
||||||
} catch (RuntimeException e) {
|
} catch (RuntimeException e) {
|
||||||
logger.trace("Query phase failed", e);
|
logger.trace("Query phase failed", e);
|
||||||
|
@ -250,10 +254,12 @@ public class SearchService extends AbstractLifecycleComponent<SearchService> {
|
||||||
public ScrollQuerySearchResult executeQueryPhase(InternalScrollSearchRequest request) throws ElasticSearchException {
|
public ScrollQuerySearchResult executeQueryPhase(InternalScrollSearchRequest request) throws ElasticSearchException {
|
||||||
SearchContext context = findContext(request.id());
|
SearchContext context = findContext(request.id());
|
||||||
try {
|
try {
|
||||||
|
long time = System.nanoTime();
|
||||||
contextProcessing(context);
|
contextProcessing(context);
|
||||||
processScroll(request, context);
|
processScroll(request, context);
|
||||||
queryPhase.execute(context);
|
queryPhase.execute(context);
|
||||||
contextProcessedSuccessfully(context);
|
contextProcessedSuccessfully(context);
|
||||||
|
context.indexShard().searchService().onQueryPhase(context, System.nanoTime() - time);
|
||||||
return new ScrollQuerySearchResult(context.queryResult(), context.shardTarget());
|
return new ScrollQuerySearchResult(context.queryResult(), context.shardTarget());
|
||||||
} catch (RuntimeException e) {
|
} catch (RuntimeException e) {
|
||||||
logger.trace("Query phase failed", e);
|
logger.trace("Query phase failed", e);
|
||||||
|
@ -275,8 +281,10 @@ public class SearchService extends AbstractLifecycleComponent<SearchService> {
|
||||||
throw new QueryPhaseExecutionException(context, "Failed to set aggregated df", e);
|
throw new QueryPhaseExecutionException(context, "Failed to set aggregated df", e);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
long time = System.nanoTime();
|
||||||
queryPhase.execute(context);
|
queryPhase.execute(context);
|
||||||
contextProcessedSuccessfully(context);
|
contextProcessedSuccessfully(context);
|
||||||
|
context.indexShard().searchService().onQueryPhase(context, System.nanoTime() - time);
|
||||||
return context.queryResult();
|
return context.queryResult();
|
||||||
} catch (RuntimeException e) {
|
} catch (RuntimeException e) {
|
||||||
logger.trace("Query phase failed", e);
|
logger.trace("Query phase failed", e);
|
||||||
|
@ -292,7 +300,10 @@ public class SearchService extends AbstractLifecycleComponent<SearchService> {
|
||||||
activeContexts.put(context.id(), context);
|
activeContexts.put(context.id(), context);
|
||||||
contextProcessing(context);
|
contextProcessing(context);
|
||||||
try {
|
try {
|
||||||
|
long time = System.nanoTime();
|
||||||
queryPhase.execute(context);
|
queryPhase.execute(context);
|
||||||
|
long time2 = System.nanoTime();
|
||||||
|
context.indexShard().searchService().onQueryPhase(context, time2 - time);
|
||||||
shortcutDocIdsToLoad(context);
|
shortcutDocIdsToLoad(context);
|
||||||
fetchPhase.execute(context);
|
fetchPhase.execute(context);
|
||||||
if (context.scroll() == null) {
|
if (context.scroll() == null) {
|
||||||
|
@ -300,6 +311,7 @@ public class SearchService extends AbstractLifecycleComponent<SearchService> {
|
||||||
} else {
|
} else {
|
||||||
contextProcessedSuccessfully(context);
|
contextProcessedSuccessfully(context);
|
||||||
}
|
}
|
||||||
|
context.indexShard().searchService().onFetchPhase(context, System.nanoTime() - time2);
|
||||||
return new QueryFetchSearchResult(context.queryResult(), context.fetchResult());
|
return new QueryFetchSearchResult(context.queryResult(), context.fetchResult());
|
||||||
} catch (RuntimeException e) {
|
} catch (RuntimeException e) {
|
||||||
logger.trace("Fetch phase failed", e);
|
logger.trace("Fetch phase failed", e);
|
||||||
|
@ -321,7 +333,10 @@ public class SearchService extends AbstractLifecycleComponent<SearchService> {
|
||||||
throw new QueryPhaseExecutionException(context, "Failed to set aggregated df", e);
|
throw new QueryPhaseExecutionException(context, "Failed to set aggregated df", e);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
long time = System.nanoTime();
|
||||||
queryPhase.execute(context);
|
queryPhase.execute(context);
|
||||||
|
long time2 = System.nanoTime();
|
||||||
|
context.indexShard().searchService().onQueryPhase(context, time2 - time);
|
||||||
shortcutDocIdsToLoad(context);
|
shortcutDocIdsToLoad(context);
|
||||||
fetchPhase.execute(context);
|
fetchPhase.execute(context);
|
||||||
if (context.scroll() == null) {
|
if (context.scroll() == null) {
|
||||||
|
@ -329,6 +344,7 @@ public class SearchService extends AbstractLifecycleComponent<SearchService> {
|
||||||
} else {
|
} else {
|
||||||
contextProcessedSuccessfully(context);
|
contextProcessedSuccessfully(context);
|
||||||
}
|
}
|
||||||
|
context.indexShard().searchService().onFetchPhase(context, System.nanoTime() - time2);
|
||||||
return new QueryFetchSearchResult(context.queryResult(), context.fetchResult());
|
return new QueryFetchSearchResult(context.queryResult(), context.fetchResult());
|
||||||
} catch (RuntimeException e) {
|
} catch (RuntimeException e) {
|
||||||
logger.trace("Fetch phase failed", e);
|
logger.trace("Fetch phase failed", e);
|
||||||
|
@ -344,7 +360,10 @@ public class SearchService extends AbstractLifecycleComponent<SearchService> {
|
||||||
contextProcessing(context);
|
contextProcessing(context);
|
||||||
try {
|
try {
|
||||||
processScroll(request, context);
|
processScroll(request, context);
|
||||||
|
long time = System.nanoTime();
|
||||||
queryPhase.execute(context);
|
queryPhase.execute(context);
|
||||||
|
long time2 = System.nanoTime();
|
||||||
|
context.indexShard().searchService().onQueryPhase(context, time2 - time);
|
||||||
shortcutDocIdsToLoad(context);
|
shortcutDocIdsToLoad(context);
|
||||||
fetchPhase.execute(context);
|
fetchPhase.execute(context);
|
||||||
if (context.scroll() == null) {
|
if (context.scroll() == null) {
|
||||||
|
@ -352,6 +371,7 @@ public class SearchService extends AbstractLifecycleComponent<SearchService> {
|
||||||
} else {
|
} else {
|
||||||
contextProcessedSuccessfully(context);
|
contextProcessedSuccessfully(context);
|
||||||
}
|
}
|
||||||
|
context.indexShard().searchService().onFetchPhase(context, System.nanoTime() - time2);
|
||||||
return new ScrollQueryFetchSearchResult(new QueryFetchSearchResult(context.queryResult(), context.fetchResult()), context.shardTarget());
|
return new ScrollQueryFetchSearchResult(new QueryFetchSearchResult(context.queryResult(), context.fetchResult()), context.shardTarget());
|
||||||
} catch (RuntimeException e) {
|
} catch (RuntimeException e) {
|
||||||
logger.trace("Fetch phase failed", e);
|
logger.trace("Fetch phase failed", e);
|
||||||
|
@ -367,12 +387,14 @@ public class SearchService extends AbstractLifecycleComponent<SearchService> {
|
||||||
contextProcessing(context);
|
contextProcessing(context);
|
||||||
try {
|
try {
|
||||||
context.docIdsToLoad(request.docIds(), 0, request.docIdsSize());
|
context.docIdsToLoad(request.docIds(), 0, request.docIdsSize());
|
||||||
|
long time = System.nanoTime();
|
||||||
fetchPhase.execute(context);
|
fetchPhase.execute(context);
|
||||||
if (context.scroll() == null) {
|
if (context.scroll() == null) {
|
||||||
freeContext(request.id());
|
freeContext(request.id());
|
||||||
} else {
|
} else {
|
||||||
contextProcessedSuccessfully(context);
|
contextProcessedSuccessfully(context);
|
||||||
}
|
}
|
||||||
|
context.indexShard().searchService().onFetchPhase(context, System.nanoTime() - time);
|
||||||
return context.fetchResult();
|
return context.fetchResult();
|
||||||
} catch (RuntimeException e) {
|
} catch (RuntimeException e) {
|
||||||
logger.trace("Fetch phase failed", e);
|
logger.trace("Fetch phase failed", e);
|
||||||
|
@ -399,7 +421,7 @@ public class SearchService extends AbstractLifecycleComponent<SearchService> {
|
||||||
SearchShardTarget shardTarget = new SearchShardTarget(clusterService.localNode().id(), request.index(), request.shardId());
|
SearchShardTarget shardTarget = new SearchShardTarget(clusterService.localNode().id(), request.index(), request.shardId());
|
||||||
|
|
||||||
Engine.Searcher engineSearcher = indexShard.searcher();
|
Engine.Searcher engineSearcher = indexShard.searcher();
|
||||||
SearchContext context = new SearchContext(idGenerator.incrementAndGet(), shardTarget, request.searchType(), request.numberOfShards(), request.nowInMillis(), request.timeout(), request.types(), engineSearcher, indexService, scriptService);
|
SearchContext context = new SearchContext(idGenerator.incrementAndGet(), shardTarget, request.searchType(), request.numberOfShards(), request.nowInMillis(), request.timeout(), request.types(), engineSearcher, indexService, indexShard, scriptService);
|
||||||
SearchContext.setCurrent(context);
|
SearchContext.setCurrent(context);
|
||||||
try {
|
try {
|
||||||
context.scroll(request.scroll());
|
context.scroll(request.scroll());
|
||||||
|
|
|
@ -107,6 +107,8 @@ public class SearchSourceBuilder implements ToXContent {
|
||||||
|
|
||||||
private TObjectFloatHashMap<String> indexBoost = null;
|
private TObjectFloatHashMap<String> indexBoost = null;
|
||||||
|
|
||||||
|
private String[] stats;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new search source builder.
|
* Constructs a new search source builder.
|
||||||
|
@ -475,6 +477,14 @@ public class SearchSourceBuilder implements ToXContent {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The stats groups this request will be aggregated under.
|
||||||
|
*/
|
||||||
|
public SearchSourceBuilder stats(String... statsGroups) {
|
||||||
|
this.stats = statsGroups;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@Override public String toString() {
|
@Override public String toString() {
|
||||||
try {
|
try {
|
||||||
XContentBuilder builder = XContentFactory.contentBuilder(XContentType.JSON).prettyPrint();
|
XContentBuilder builder = XContentFactory.contentBuilder(XContentType.JSON).prettyPrint();
|
||||||
|
@ -630,6 +640,14 @@ public class SearchSourceBuilder implements ToXContent {
|
||||||
highlightBuilder.toXContent(builder, params);
|
highlightBuilder.toXContent(builder, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (stats != null) {
|
||||||
|
builder.startArray("stats");
|
||||||
|
for (String stat : stats) {
|
||||||
|
builder.value(stat);
|
||||||
|
}
|
||||||
|
builder.endArray();
|
||||||
|
}
|
||||||
|
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ import org.apache.lucene.search.Query;
|
||||||
import org.apache.lucene.search.Sort;
|
import org.apache.lucene.search.Sort;
|
||||||
import org.elasticsearch.ElasticSearchException;
|
import org.elasticsearch.ElasticSearchException;
|
||||||
import org.elasticsearch.action.search.SearchType;
|
import org.elasticsearch.action.search.SearchType;
|
||||||
|
import org.elasticsearch.common.Nullable;
|
||||||
import org.elasticsearch.common.collect.ImmutableList;
|
import org.elasticsearch.common.collect.ImmutableList;
|
||||||
import org.elasticsearch.common.collect.Lists;
|
import org.elasticsearch.common.collect.Lists;
|
||||||
import org.elasticsearch.common.lease.Releasable;
|
import org.elasticsearch.common.lease.Releasable;
|
||||||
|
@ -38,6 +39,7 @@ import org.elasticsearch.index.query.IndexQueryParserService;
|
||||||
import org.elasticsearch.index.query.ParsedQuery;
|
import org.elasticsearch.index.query.ParsedQuery;
|
||||||
import org.elasticsearch.index.search.nested.BlockJoinQuery;
|
import org.elasticsearch.index.search.nested.BlockJoinQuery;
|
||||||
import org.elasticsearch.index.service.IndexService;
|
import org.elasticsearch.index.service.IndexService;
|
||||||
|
import org.elasticsearch.index.shard.service.IndexShard;
|
||||||
import org.elasticsearch.index.similarity.SimilarityService;
|
import org.elasticsearch.index.similarity.SimilarityService;
|
||||||
import org.elasticsearch.script.ScriptService;
|
import org.elasticsearch.script.ScriptService;
|
||||||
import org.elasticsearch.search.Scroll;
|
import org.elasticsearch.search.Scroll;
|
||||||
|
@ -86,6 +88,8 @@ public class SearchContext implements Releasable {
|
||||||
|
|
||||||
private final ScriptService scriptService;
|
private final ScriptService scriptService;
|
||||||
|
|
||||||
|
private final IndexShard indexShard;
|
||||||
|
|
||||||
private final IndexService indexService;
|
private final IndexService indexService;
|
||||||
|
|
||||||
private final ContextIndexSearcher searcher;
|
private final ContextIndexSearcher searcher;
|
||||||
|
@ -103,6 +107,8 @@ public class SearchContext implements Releasable {
|
||||||
private float queryBoost = 1.0f;
|
private float queryBoost = 1.0f;
|
||||||
|
|
||||||
|
|
||||||
|
private List<String> groupStats;
|
||||||
|
|
||||||
private Scroll scroll;
|
private Scroll scroll;
|
||||||
|
|
||||||
private boolean explain;
|
private boolean explain;
|
||||||
|
@ -156,7 +162,7 @@ public class SearchContext implements Releasable {
|
||||||
private Map<String, BlockJoinQuery> nestedQueries;
|
private Map<String, BlockJoinQuery> nestedQueries;
|
||||||
|
|
||||||
public SearchContext(long id, SearchShardTarget shardTarget, SearchType searchType, int numberOfShards, long nowInMillis, TimeValue timeout,
|
public SearchContext(long id, SearchShardTarget shardTarget, SearchType searchType, int numberOfShards, long nowInMillis, TimeValue timeout,
|
||||||
String[] types, Engine.Searcher engineSearcher, IndexService indexService, ScriptService scriptService) {
|
String[] types, Engine.Searcher engineSearcher, IndexService indexService, IndexShard indexShard, ScriptService scriptService) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.nowInMillis = nowInMillis;
|
this.nowInMillis = nowInMillis;
|
||||||
this.searchType = searchType;
|
this.searchType = searchType;
|
||||||
|
@ -169,6 +175,7 @@ public class SearchContext implements Releasable {
|
||||||
this.dfsResult = new DfsSearchResult(id, shardTarget);
|
this.dfsResult = new DfsSearchResult(id, shardTarget);
|
||||||
this.queryResult = new QuerySearchResult(id, shardTarget);
|
this.queryResult = new QuerySearchResult(id, shardTarget);
|
||||||
this.fetchResult = new FetchSearchResult(id, shardTarget);
|
this.fetchResult = new FetchSearchResult(id, shardTarget);
|
||||||
|
this.indexShard = indexShard;
|
||||||
this.indexService = indexService;
|
this.indexService = indexService;
|
||||||
|
|
||||||
this.searcher = new ContextIndexSearcher(this, engineSearcher);
|
this.searcher = new ContextIndexSearcher(this, engineSearcher);
|
||||||
|
@ -274,6 +281,10 @@ public class SearchContext implements Releasable {
|
||||||
return this.searcher;
|
return this.searcher;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IndexShard indexShard() {
|
||||||
|
return this.indexShard;
|
||||||
|
}
|
||||||
|
|
||||||
public MapperService mapperService() {
|
public MapperService mapperService() {
|
||||||
return indexService.mapperService();
|
return indexService.mapperService();
|
||||||
}
|
}
|
||||||
|
@ -430,6 +441,14 @@ public class SearchContext implements Releasable {
|
||||||
this.explain = explain;
|
this.explain = explain;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable public List<String> groupStats() {
|
||||||
|
return this.groupStats;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void groupStats(List<String> groupStats) {
|
||||||
|
this.groupStats = groupStats;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean version() {
|
public boolean version() {
|
||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
/*
|
||||||
|
* 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.test.integration.search.stats;
|
||||||
|
|
||||||
|
import org.elasticsearch.action.admin.cluster.node.stats.NodesStatsResponse;
|
||||||
|
import org.elasticsearch.action.admin.indices.stats.IndicesStats;
|
||||||
|
import org.elasticsearch.client.Client;
|
||||||
|
import org.elasticsearch.common.settings.Settings;
|
||||||
|
import org.elasticsearch.index.query.QueryBuilders;
|
||||||
|
import org.elasticsearch.test.integration.AbstractNodesTests;
|
||||||
|
import org.testng.annotations.AfterClass;
|
||||||
|
import org.testng.annotations.BeforeClass;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import static org.elasticsearch.common.settings.ImmutableSettings.*;
|
||||||
|
import static org.hamcrest.MatcherAssert.*;
|
||||||
|
import static org.hamcrest.Matchers.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
public class SearchStatsTests extends AbstractNodesTests {
|
||||||
|
|
||||||
|
private Client client;
|
||||||
|
|
||||||
|
@BeforeClass public void createNodes() throws Exception {
|
||||||
|
Settings settings = settingsBuilder().put("number_of_shards", 3).put("number_of_replicas", 0).build();
|
||||||
|
startNode("server1", settings);
|
||||||
|
startNode("server2", settings);
|
||||||
|
client = getClient();
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterClass public void closeNodes() {
|
||||||
|
client.close();
|
||||||
|
closeAllNodes();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Client getClient() {
|
||||||
|
return client("server1");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test public void testSimpleStats() throws Exception {
|
||||||
|
client.admin().indices().prepareDelete().execute().actionGet();
|
||||||
|
|
||||||
|
for (int i = 0; i < 100; i++) {
|
||||||
|
client.prepareIndex("test1", "type", Integer.toString(i)).setSource("field", "value").execute().actionGet();
|
||||||
|
}
|
||||||
|
for (int i = 0; i < 100; i++) {
|
||||||
|
client.prepareIndex("test2", "type", Integer.toString(i)).setSource("field", "value").execute().actionGet();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 50; i++) {
|
||||||
|
client.prepareSearch().setQuery(QueryBuilders.termQuery("field", "value")).setStats("group1", "group2").execute().actionGet();
|
||||||
|
}
|
||||||
|
|
||||||
|
IndicesStats indicesStats = client.admin().indices().prepareStats().execute().actionGet();
|
||||||
|
assertThat(indicesStats.total().search().total().queryCount(), greaterThan(0l));
|
||||||
|
assertThat(indicesStats.total().search().total().queryTimeInMillis(), greaterThan(0l));
|
||||||
|
assertThat(indicesStats.total().search().total().fetchCount(), greaterThan(0l));
|
||||||
|
assertThat(indicesStats.total().search().total().fetchTimeInMillis(), greaterThan(0l));
|
||||||
|
assertThat(indicesStats.total().search().groupStats(), nullValue());
|
||||||
|
|
||||||
|
indicesStats = client.admin().indices().prepareStats().setGroups("group1").execute().actionGet();
|
||||||
|
assertThat(indicesStats.total().search().groupStats(), notNullValue());
|
||||||
|
assertThat(indicesStats.total().search().groupStats().get("group1").queryCount(), greaterThan(0l));
|
||||||
|
assertThat(indicesStats.total().search().groupStats().get("group1").queryTimeInMillis(), greaterThan(0l));
|
||||||
|
assertThat(indicesStats.total().search().groupStats().get("group1").fetchCount(), greaterThan(0l));
|
||||||
|
assertThat(indicesStats.total().search().groupStats().get("group1").fetchTimeInMillis(), greaterThan(0l));
|
||||||
|
|
||||||
|
NodesStatsResponse nodeStats = client.admin().cluster().prepareNodesStats().execute().actionGet();
|
||||||
|
assertThat(nodeStats.nodes()[0].indices().search().total().queryCount(), greaterThan(0l));
|
||||||
|
assertThat(nodeStats.nodes()[0].indices().search().total().queryTimeInMillis(), greaterThan(0l));
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue