Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/Nest/Nest.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -1275,6 +1275,8 @@
<Compile Include="Search\Search\Hits\InnerHitsResult.cs" />
<Compile Include="Search\Search\Hits\NestedIdentity.cs" />
<Compile Include="Search\Search\InnerHits\InnerHits.cs" />
<Compile Include="Search\Search\Profile\AggregationBreakdown.cs" />
<Compile Include="Search\Search\Profile\AggregationProfile.cs" />
<Compile Include="Search\Search\Profile\Collector.cs" />
<Compile Include="Search\Search\Profile\Profile.cs" />
<Compile Include="Search\Search\Profile\QueryBreakdown.cs" />
Expand Down
32 changes: 32 additions & 0 deletions src/Nest/Search/Search/Profile/AggregationBreakdown.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System.Collections.Generic;
using Newtonsoft.Json;

namespace Nest
{
public class AggregationBreakdown
{
[JsonProperty("reduce")]
public long Reduce { get; internal set; }

[JsonProperty("build_aggregation")]
public long BuildAggregation { get; internal set; }

[JsonProperty("build_aggregation_count")]
public long BuildAggregationCount { get; internal set; }

[JsonProperty("initialize")]
public long Initialize { get; internal set; }

[JsonProperty("intialize_count")]
public long InitializeCount { get; internal set; }

[JsonProperty("reduce_count")]
public long ReduceCount { get; internal set; }

[JsonProperty("collect")]
public long Collect { get; internal set; }

[JsonProperty("collect_count")]
public long CollectCount { get; internal set; }
}
}
38 changes: 38 additions & 0 deletions src/Nest/Search/Search/Profile/AggregationProfile.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using System.Collections.Generic;
using Newtonsoft.Json;

namespace Nest
{
public class AggregationProfile
{
/// <summary>
/// The Elasticsearch aggregation type
/// </summary>
[JsonProperty("type")]
public string Type { get; internal set; }

/// <summary>
/// The user defined name of the aggregation
/// </summary>
[JsonProperty("description")]
public string Description { get; internal set; }

/// <summary>
/// The time this aggregation took
/// </summary>
[JsonProperty("time")]
public Time Time { get; internal set; }

/// <summary>
/// The time this aggregation took, in nanoseconds
/// </summary>
[JsonProperty("time_in_nanos")]
public long TimeInNanoseconds { get; internal set; }

/// <summary>
/// Detailed stats about how the time was spent
/// </summary>
[JsonProperty("breakdown")]
public AggregationBreakdown Breakdown { get; internal set; }
}
}
5 changes: 4 additions & 1 deletion src/Nest/Search/Search/Profile/Collector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ public class Collector
[JsonProperty("time")]
public Time Time { get; internal set; }

[JsonProperty("children")]
[JsonProperty("time_in_nanos")]
public long TimeInNanoseconds { get; internal set; }

[JsonProperty("children")]
public IReadOnlyCollection<Collector> Children { get; internal set; } =
EmptyReadOnly<Collector>.Collection;

Expand Down
6 changes: 6 additions & 0 deletions src/Nest/Search/Search/Profile/QueryProfile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ public class QueryProfile
[JsonProperty("time")]
public Time Time { get; internal set; }

/// <summary>
/// The time that this query took in nanoseconds
/// </summary>
[JsonProperty("time_in_nanos")]
public long TimeInNanoseconds { get; internal set; }

/// <summary>
/// Detailed stats about how the time was spent
/// </summary>
Expand Down
3 changes: 3 additions & 0 deletions src/Nest/Search/Search/Profile/ShardProfile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,8 @@ public class ShardProfile
public IReadOnlyCollection<SearchProfile> Searches { get; internal set; } =
EmptyReadOnly<SearchProfile>.Collection;

[JsonProperty("aggregations")]
public IReadOnlyCollection<AggregationProfile> Aggregations { get; internal set; } =
EmptyReadOnly<AggregationProfile>.Collection;
}
}
140 changes: 140 additions & 0 deletions src/Tests/Search/Search/SearchProfileApiTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Elasticsearch.Net;
using FluentAssertions;
using Nest;
using Tests.Framework;
using Tests.Framework.Integration;
using Tests.Framework.MockData;

namespace Tests.Search.Search
{
public class SearchProfileApiTests : ApiIntegrationTestBase<ReadOnlyCluster, ISearchResponse<Project>, ISearchRequest,
SearchDescriptor<Project>, SearchRequest<Project>>
{
public SearchProfileApiTests(ReadOnlyCluster cluster, EndpointUsage usage) : base(cluster, usage)
{
}

protected override LazyResponses ClientUsage() => Calls(
fluent: (c, f) => c.Search(f),
fluentAsync: (c, f) => c.SearchAsync(f),
request: (c, r) => c.Search<Project>(r),
requestAsync: (c, r) => c.SearchAsync<Project>(r)
);

protected override int ExpectStatusCode => 200;
protected override bool ExpectIsValid => true;
protected override HttpMethod HttpMethod => HttpMethod.POST;
protected override string UrlPath => $"/project/project/_search";

protected override object ExpectJson => new
{
profile = true,
query = new
{
match_all = new { }
},
aggs = new
{
startDates = new
{
terms = new
{
field = "startedOn"
}
}
}
};

protected override void ExpectResponse(ISearchResponse<Project> response)
{
response.Hits.Count().Should().BeGreaterThan(0);
var profile = response.Profile;
profile.Should().NotBeNull();
var shardProfiles = profile.Shards;
shardProfiles.Should().NotBeNullOrEmpty();
foreach (var shardProfile in shardProfiles)
{
shardProfile.Id.Should().NotBeNullOrEmpty();
var searches = shardProfile.Searches;
searches.Should().NotBeNullOrEmpty();
foreach (var search in searches)
{
var queries = search.Query;
queries.Should().NotBeNullOrEmpty();
foreach (var query in queries)
{
query.Should().NotBeNull();
query.Type.Should().NotBeNullOrEmpty();
query.Description.Should().NotBeNullOrEmpty();
query.Time.Should().NotBeNull();
query.TimeInNanoseconds.Should().BeGreaterThan(0);
query.Breakdown.Should().NotBeNull();
}
search.RewriteTime.Should().BeGreaterThan(0);
var collectors = search.Collector;
foreach (var collector in collectors)
{
collector.Name.Should().NotBeNullOrEmpty();
collector.Reason.Should().NotBeNullOrEmpty();
collector.Time.Should().NotBeNull();
collector.TimeInNanoseconds.Should().BeGreaterThan(0);
var children = collector.Children;
children.Should().NotBeNull();
foreach (var child in children)
{
child.Should().NotBeNull();
child.Name.Should().NotBeNullOrEmpty();
child.Reason.Should().NotBeNullOrEmpty();
child.Time.Should().NotBeNull();
child.TimeInNanoseconds.Should().BeGreaterThan(0);
var grandchildren = child.Children;
grandchildren.Should().NotBeNull();
foreach (var grandchild in grandchildren)
{
grandchild.Name.Should().NotBeNullOrEmpty();
grandchild.Reason.Should().NotBeNullOrEmpty();
grandchild.Time.Should().NotBeNull();
grandchild.TimeInNanoseconds.Should().BeGreaterThan(0);
}
}
}
}
var aggregations = shardProfile.Aggregations;
aggregations.Should().NotBeNull();
foreach (var aggregation in aggregations)
{
aggregation.Should().NotBeNull();
aggregation.Type.Should().NotBeNullOrEmpty();
aggregation.Description.Should().NotBeNullOrEmpty();
aggregation.Time.Should().NotBeNull();
aggregation.TimeInNanoseconds.Should().BeGreaterThan(0);
aggregation.Breakdown.Should().NotBeNull();
}
}
}

protected override Func<SearchDescriptor<Project>, ISearchRequest> Fluent => s => s
.Profile()
.Query(q => q
.MatchAll()
)
.Aggregations(aggs => aggs
.Terms("startDates", t => t
.Field(p => p.StartedOn)
)
);

protected override SearchRequest<Project> Initializer => new SearchRequest<Project>()
{
Profile = true,
Query = new QueryContainer(new MatchAllQuery()),
Aggregations = new TermsAggregation("startDates")
{
Field = "startedOn"
}
};
}
}
1 change: 1 addition & 0 deletions src/Tests/Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -722,6 +722,7 @@
<Compile Include="Search\Scroll\Scroll\SlicedScrollSearchApiTests.cs" />
<Compile Include="Search\Search\InvalidSearchApiTests.cs" />
<Compile Include="Search\Search\Rescoring\RescoreUsageTests.cs" />
<Compile Include="Search\Search\SearchProfileApiTests.cs" />
<Compile Include="Search\Search\SearchProfileTests.cs" />
<Compile Include="Search\Suggesters\SuggestUrlTests.cs" />
<Compile Include="XPack\Security\ClearCachedRealms\ClearCachedRealmsApiTests.cs" />
Expand Down
2 changes: 1 addition & 1 deletion src/Tests/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
mode: m
# the elasticsearch version that should be started
# Can be a snapshot version of sonatype or "latest" to get the latest snapshot of sonatype
elasticsearch_version: latest
elasticsearch_version: 5.3.0-SNAPSHOT
# cluster filter allows you to only run the integration tests of a particular cluster (cluster suffix not needed)
# cluster_filter:
# whether we want to forcefully reseed on the node, if you are starting the tests with a node already running
Expand Down