Skip to content

Commit 31e6466

Browse files
committed
added support for Top Hits aggregation
1 parent bbdccfa commit 31e6466

File tree

6 files changed

+89
-11
lines changed

6 files changed

+89
-11
lines changed

src/Nest/Domain/Aggregations/AggregationsHelper.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,11 @@ public PercentilesMetric PercentilesRank(string key)
8181
return this.TryGet<PercentilesMetric>(key);
8282
}
8383

84+
public TopHitsMetric TopHitsMetric(string key)
85+
{
86+
return this.TryGet<TopHitsMetric>(key);
87+
}
88+
8489
public SingleBucket Global(string key)
8590
{
8691
return this.TryGet<SingleBucket>(key);
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using Newtonsoft.Json;
6+
using Newtonsoft.Json.Linq;
7+
8+
namespace Nest
9+
{
10+
public class TopHitsMetric : IMetricAggregation
11+
{
12+
private IEnumerable<JObject> _hits;
13+
14+
public TopHitsMetric()
15+
{
16+
}
17+
18+
internal TopHitsMetric(IEnumerable<JObject> hits)
19+
{
20+
_hits = hits;
21+
}
22+
23+
public long Total { get; set; }
24+
public double? MaxScore { get; set; }
25+
26+
public IEnumerable<Hit<T>> Hits<T>(JsonSerializer serializer = null) where T : class
27+
{
28+
if (serializer != null)
29+
return _hits.Select(h => h.ToObject<Hit<T>>(serializer));
30+
return _hits.Select(h => h.ToObject<Hit<T>>());
31+
}
32+
33+
public IEnumerable<T> Documents<T>(JsonSerializer serializer = null) where T : class
34+
{
35+
return this.Hits<T>(serializer).Select(h => h.Source);
36+
}
37+
38+
39+
}
40+
41+
}

src/Nest/Domain/Hit/Hit.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ public interface IHit<out T> where T : class
1212
IFieldSelection<T> Fields { get; }
1313
T Source { get; }
1414
string Index { get; }
15-
double Score { get; }
15+
double? Score { get; }
1616
string Type { get; }
1717
string Version { get; }
1818
string Id { get; }
@@ -36,7 +36,7 @@ public class Hit<T> : IHit<T>
3636
[JsonProperty(PropertyName = "_index")]
3737
public string Index { get; internal set; }
3838
[JsonProperty(PropertyName = "_score")]
39-
public double Score { get; internal set; }
39+
public double? Score { get; internal set; }
4040
[JsonProperty(PropertyName = "_type")]
4141
public string Type { get; internal set; }
4242
[JsonProperty(PropertyName = "_version")]

src/Nest/Nest.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@
106106
<Compile Include="Domain\Aggregations\AggregationsHelper.cs" />
107107
<Compile Include="Domain\Aggregations\Bucket.cs" />
108108
<Compile Include="Domain\Aggregations\BucketAggregationBase.cs" />
109+
<Compile Include="Domain\Aggregations\TopHitsMetric.cs" />
109110
<Compile Include="Domain\Aggregations\GeoBoundsMetric.cs" />
110111
<Compile Include="Domain\Aggregations\HistogramItem.cs" />
111112
<Compile Include="Domain\Aggregations\ExtendedStatsMetric.cs" />

src/Nest/Resolvers/Converters/Aggregations/AggregationConverter.cs

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,27 @@ private IAggregation ReadAggregation(JsonReader reader, JsonSerializer serialize
5959
return GetSingleBucketAggregation(reader, serializer);
6060
case "bounds":
6161
return GetGeoBoundsMetricAggregation(reader, serializer);
62+
case "hits":
63+
return GetHitsAggregation(reader, serializer);
6264
default:
6365
return null;
6466

6567
}
6668
}
6769

70+
private IAggregation GetHitsAggregation(JsonReader reader, JsonSerializer serializer)
71+
{
72+
reader.Read();
73+
var o = JObject.Load(reader);
74+
if (o == null)
75+
return null;
76+
77+
var total = o["total"].ToObject<long>();
78+
var maxScore = o["max_score"].ToObject<double?>();
79+
var hits = o["hits"].Children().OfType<JObject>().Select(s=>s);
80+
return new TopHitsMetric(hits) { Total = total, MaxScore = maxScore };
81+
}
82+
6883
private IAggregation GetGeoBoundsMetricAggregation(JsonReader reader, JsonSerializer serializer)
6984
{
7085
reader.Read();
@@ -369,15 +384,15 @@ public IAggregation GetRangeAggregation(JsonReader reader, JsonSerializer serial
369384
break;
370385
}
371386
}
372-
var bucket = new RangeItem
373-
{
374-
Key = key,
375-
From = fromDouble,
376-
To = toDouble,
377-
DocCount = docCount.GetValueOrDefault(),
378-
FromAsString = fromAsString,
379-
ToAsString = toAsString
380-
};
387+
var bucket = new RangeItem
388+
{
389+
Key = key,
390+
From = fromDouble,
391+
To = toDouble,
392+
DocCount = docCount.GetValueOrDefault(),
393+
FromAsString = fromAsString,
394+
ToAsString = toAsString
395+
};
381396

382397
bucket.Aggregations = this.GetNestedAggregations(reader, serializer);
383398
return bucket;

src/Tests/Nest.Tests.Integration/Aggregations/MetricAggregationTests.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.Linq;
2+
using Elasticsearch.Net;
23
using FluentAssertions;
34
using Nest.Tests.MockData.Domain;
45
using NUnit.Framework;
@@ -187,6 +188,21 @@ public void TopHits()
187188
)
188189
)
189190
);
191+
192+
results.IsValid.Should().BeTrue();
193+
194+
var topCountries = results.Aggs.Terms("top-countries").Items;
195+
foreach(var topCountry in topCountries)
196+
{
197+
var topHits = topCountry.TopHitsMetric("top-country-hits");
198+
topHits.Should().NotBeNull();
199+
topHits.Total.Should().BeGreaterThan(0);
200+
var hits = topHits.Hits<ElasticsearchProject>();
201+
hits.Should().NotBeEmpty().And.NotContain(h=> h.Id.IsNullOrEmpty() || h.Index.IsNullOrEmpty());
202+
topHits.Documents<ElasticsearchProject>().Should().NotBeEmpty();
203+
204+
}
205+
190206
}
191207
}
192208
}

0 commit comments

Comments
 (0)