Skip to content

Commit 36eb6c0

Browse files
committed
Merge branch 'develop' into feature/aggregations-top-hits
2 parents 31e6466 + 2166c65 commit 36eb6c0

File tree

22 files changed

+516
-91
lines changed

22 files changed

+516
-91
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
---
2+
template: layout.jade
3+
title: Aggregations
4+
menusection: aggregations
5+
menuitem: advanced
6+
---
7+
8+
# Advanced usage
9+
10+
## Creating multiple aggregations from an IEnumerable
11+
12+
Premise:
13+
You have an IEnumerable<TestObject> MyFilters, and you want to build a Filter aggregation with a Term filter for each of the TestObjects you have.
14+
15+
class TestObject
16+
{
17+
public string Name { get; set; }
18+
public string Term { get; set; }
19+
}
20+
21+
Then you could do something like this:
22+
23+
IEnumerable<TestObject> MyFilters;
24+
25+
var descriptor = new SearchDescriptor<MySearchType>().Query(q => q.MatchAll());
26+
27+
descriptor.Aggregations(aggr =>
28+
{
29+
foreach (var term in MyFilters)
30+
{
31+
aggr.Filter(term.Name, filter => filter
32+
.Filter(f => f
33+
.Term("TheTermField", term.Term)))
34+
}
35+
36+
return aggr;
37+
});
38+
39+
var result = client.Search<MySearchType>(descriptor);
40+
41+
And then you can access the aggregation results as normal.

src/Connections/Elasticsearch.Net.Connection.HttpClient/HttpClientConnection.cs

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.Net;
44
using System.Net.Http;
55
using System.Net.Http.Headers;
6+
using System.Text;
67
using System.Threading.Tasks;
78
using Elasticsearch.Net.Connection.Configuration;
89

@@ -37,10 +38,14 @@ public HttpClientConnection(IConnectionConfigurationValues settings, HttpClientH
3738

3839
var innerHandler = handler ?? new WebRequestHandler();
3940

41+
if (settings.EnableCompressedResponses)
42+
innerHandler.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
43+
4044
if (innerHandler.SupportsProxy && !string.IsNullOrWhiteSpace(_settings.ProxyAddress))
4145
{
4246
innerHandler.Proxy = new WebProxy(_settings.ProxyAddress)
4347
{
48+
4449
Credentials = new NetworkCredential(_settings.ProxyUsername, _settings.ProxyPassword),
4550
};
4651

@@ -51,6 +56,7 @@ public HttpClientConnection(IConnectionConfigurationValues settings, HttpClientH
5156
{
5257
Timeout = TimeSpan.FromMilliseconds(_settings.Timeout)
5358
};
59+
5460
}
5561

5662
/// <summary>
@@ -115,24 +121,22 @@ public async Task<ElasticsearchResponse<Stream>> DoRequest(HttpMethod method, Ur
115121
try
116122
{
117123
var request = new HttpRequestMessage(method, uri);
124+
if (requestSpecificConfig != null && !string.IsNullOrWhiteSpace(requestSpecificConfig.ContentType))
125+
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(requestSpecificConfig.ContentType));
126+
else if (!string.IsNullOrWhiteSpace(DefaultContentType))
127+
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(DefaultContentType));
128+
129+
if (!string.IsNullOrWhiteSpace(DefaultContentType))
130+
request.Content.Headers.ContentType = new MediaTypeHeaderValue(DefaultContentType);
131+
132+
if (!string.IsNullOrEmpty(uri.UserInfo))
133+
{
134+
request.Headers.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.UTF8.GetBytes(uri.UserInfo)));
135+
}
118136

119137
if (method != HttpMethod.Get && method != HttpMethod.Head && data != null && data.Length > 0)
120138
{
121139
request.Content = new ByteArrayContent(data);
122-
123-
if (requestSpecificConfig != null && !string.IsNullOrWhiteSpace(requestSpecificConfig.ContentType))
124-
{
125-
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(requestSpecificConfig.ContentType));
126-
}
127-
else if (!string.IsNullOrWhiteSpace(DefaultContentType))
128-
{
129-
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(DefaultContentType));
130-
}
131-
132-
if (!string.IsNullOrWhiteSpace(DefaultContentType))
133-
{
134-
request.Content.Headers.ContentType = new MediaTypeHeaderValue(DefaultContentType);
135-
}
136140
}
137141

138142
var response = await Client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);

src/Elasticsearch.Net/Connection/HttpConnection.cs

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ private static void ThreadTimeoutCallback(object state, bool timedOut)
141141
protected virtual HttpWebRequest CreateHttpWebRequest(Uri uri, string method, byte[] data, IRequestConfiguration requestSpecificConfig)
142142
{
143143
var myReq = this.CreateWebRequest(uri, method, data, requestSpecificConfig);
144-
this.SetBasicAuthorizationIfNeeded(myReq);
144+
this.SetBasicAuthorizationIfNeeded(uri, myReq);
145145
this.SetProxyIfNeeded(myReq);
146146
return myReq;
147147
}
@@ -164,15 +164,12 @@ private void SetProxyIfNeeded(HttpWebRequest myReq)
164164
}
165165
}
166166

167-
private void SetBasicAuthorizationIfNeeded(HttpWebRequest myReq)
167+
private void SetBasicAuthorizationIfNeeded(Uri uri, HttpWebRequest myReq)
168168
{
169-
//TODO figure out a way to cache this;
170-
171-
//if (this._ConnectionSettings.UriSpecifiedBasicAuth)
172-
//{
173-
myReq.Headers["Authorization"] =
174-
"Basic " + Convert.ToBase64String(Encoding.UTF8.GetBytes(myReq.RequestUri.UserInfo));
175-
//}
169+
if (!uri.UserInfo.IsNullOrEmpty())
170+
{
171+
myReq.Headers["Authorization"] = "Basic " + Convert.ToBase64String(Encoding.UTF8.GetBytes(myReq.RequestUri.UserInfo));
172+
}
176173
}
177174

178175
protected virtual HttpWebRequest CreateWebRequest(Uri uri, string method, byte[] data, IRequestConfiguration requestSpecificConfig)

src/Elasticsearch.Net/Connection/RequestState/TransportRequestState.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Linq;
66
using System.Text;
77
using Elasticsearch.Net.Connection.Configuration;
8+
using Elasticsearch.Net.ConnectionPool;
89
using PurifyNet;
910

1011
namespace Elasticsearch.Net.Connection.RequestState
@@ -29,6 +30,15 @@ public IRequestConfiguration RequestConfiguration
2930
}
3031
}
3132

33+
public bool UsingPooling
34+
{
35+
get
36+
{
37+
var pool = this.ClientSettings.ConnectionPool;
38+
return pool != null && pool.GetType() != typeof(SingleNodeConnectionPool);
39+
}
40+
}
41+
3242
public string Method { get; private set; }
3343

3444
public string Path { get; private set; }

src/Elasticsearch.Net/Connection/Transport.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,7 @@ private ElasticsearchResponse<T> DoRequest<T>(TransportRequestState<T> requestSt
369369
catch (Exception e)
370370
{
371371
requestState.SeenExceptions.Add(e);
372-
if (maxRetries == 0 && retried == 0)
372+
if (!requestState.UsingPooling || maxRetries == 0 && retried == 0)
373373
{
374374
if (_throwMaxRetry)
375375
new MaxRetryException(e);
@@ -489,8 +489,8 @@ private Task<ElasticsearchResponse<T>> FinishOrRetryRequestAsync<T>(TransportReq
489489
if (t.IsFaulted)
490490
{
491491
rq.Dispose();
492-
if (maxRetries == 0 && retried == 0) throw t.Exception;
493492
requestState.SeenExceptions.Add(t.Exception);
493+
if (!requestState.UsingPooling || maxRetries == 0 && retried == 0) throw t.Exception;
494494
return this.RetryRequestAsync<T>(requestState);
495495
}
496496

@@ -633,13 +633,13 @@ private ElasticsearchServerError ThrowOrGetErrorFromStreamResponse<T>(
633633
TransportRequestState<T> requestState,
634634
ElasticsearchResponse<Stream> streamResponse)
635635
{
636-
if (IsValidResponse(requestState, streamResponse))
637-
return null;
638-
639636
if (((streamResponse.HttpStatusCode.HasValue && streamResponse.HttpStatusCode.Value <= 0)
640637
|| !streamResponse.HttpStatusCode.HasValue) && streamResponse.OriginalException != null)
641638
throw streamResponse.OriginalException;
642639

640+
if (IsValidResponse(requestState, streamResponse))
641+
return null;
642+
643643
ElasticsearchServerError error = null;
644644

645645
var type = typeof(T);

src/Elasticsearch.Net/Domain/Response/ElasticsearchResponse.cs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.CodeDom;
33
using System.Collections.Generic;
4+
using System.ComponentModel;
45
using System.Configuration;
56
using System.Globalization;
67
using System.Linq;
@@ -12,6 +13,7 @@
1213
using System.Threading.Tasks;
1314
using Elasticsearch.Net;
1415
using Elasticsearch.Net.Connection;
16+
using Elasticsearch.Net.ConnectionPool;
1517
using Elasticsearch.Net.Exceptions;
1618
using Elasticsearch.Net.Serialization;
1719

@@ -125,8 +127,12 @@ public bool SuccessOrKnownError
125127
{
126128
get
127129
{
130+
var pool = this.Settings.ConnectionPool;
131+
var usingPool = pool != null && pool.GetType() != typeof(SingleNodeConnectionPool);
132+
128133
return this.Success ||
129-
(this.HttpStatusCode.HasValue
134+
(!usingPool && this.HttpStatusCode.GetValueOrDefault(1) < 0)
135+
|| (this.HttpStatusCode.HasValue
130136
&& this.HttpStatusCode.Value != 503 //service unavailable needs to be retried
131137
&& this.HttpStatusCode.Value != 502 //bad gateway needs to be retried
132138
&& ((this.HttpStatusCode.Value >= 400 && this.HttpStatusCode.Value < 599)));
@@ -162,22 +168,26 @@ public static ElasticsearchResponse<T> CreateError(IConnectionConfigurationValue
162168
return cs;
163169
}
164170

165-
public static ElasticsearchResponse<T> Create(IConnectionConfigurationValues settings, int statusCode, string method, string path, byte[] request)
171+
public static ElasticsearchResponse<T> Create(
172+
IConnectionConfigurationValues settings, int statusCode, string method, string path, byte[] request, Exception innerException = null)
166173
{
167174
var cs = new ElasticsearchResponse<T>(settings, statusCode);
168175
cs.Request = request;
169176
cs.RequestUrl = path;
170177
cs.RequestMethod = method;
178+
cs.OriginalException = innerException;
171179
return cs;
172180
}
173181

174-
public static ElasticsearchResponse<T> Create(IConnectionConfigurationValues settings, int statusCode, string method, string path, byte[] request, T response)
182+
public static ElasticsearchResponse<T> Create(
183+
IConnectionConfigurationValues settings, int statusCode, string method, string path, byte[] request, T response, Exception innerException = null)
175184
{
176185
var cs = new ElasticsearchResponse<T>(settings, statusCode);
177186
cs.Request = request;
178187
cs.RequestUrl = path;
179188
cs.RequestMethod = method;
180189
cs.Response = response;
190+
cs.OriginalException = innerException;
181191
return cs;
182192
}
183193

src/Elasticsearch.Net/ElasticsearchClient.cs

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,14 +50,31 @@ public string Encoded(object o)
5050
return Uri.EscapeDataString(this.Serializer.Stringify(o));
5151
}
5252

53-
54-
protected ElasticsearchResponse<T> DoRequest<T>(string method, string path, object data = null, IRequestParameters requestParameters = null)
53+
54+
/// <summary>
55+
/// Perform any request you want over the configured IConnection synchronously while taking advantage of the cluster failover.
56+
/// </summary>
57+
/// <typeparam name="T">The type representing the response JSON</typeparam>
58+
/// <param name="method">the HTTP Method to use</param>
59+
/// <param name="path">The path of the the url that you would like to hit</param>
60+
/// <param name="data">The body of the request, string and byte[] are posted as is other types will be serialized to JSON</param>
61+
/// <param name="requestParameters">Optionally configure request specific timeouts, headers</param>
62+
/// <returns>An ElasticsearchResponse of T where T represents the JSON response body</returns>
63+
public ElasticsearchResponse<T> DoRequest<T>(string method, string path, object data = null, IRequestParameters requestParameters = null)
5564
{
5665
return this.Transport.DoRequest<T>(method, path, data, requestParameters);
5766
}
5867

59-
60-
protected Task<ElasticsearchResponse<T>> DoRequestAsync<T>(string method, string path, object data = null, IRequestParameters requestParameters = null)
68+
/// <summary>
69+
/// Perform any request you want over the configured IConnection asynchronously while taking advantage of the cluster failover.
70+
/// </summary>
71+
/// <typeparam name="T">The type representing the response JSON</typeparam>
72+
/// <param name="method">the HTTP Method to use</param>
73+
/// <param name="path">The path of the the url that you would like to hit</param>
74+
/// <param name="data">The body of the request, string and byte[] are posted as is other types will be serialized to JSON</param>
75+
/// <param name="requestParameters">Optionally configure request specific timeouts, headers</param>
76+
/// <returns>A task of ElasticsearchResponse of T where T represents the JSON response body</returns>
77+
public Task<ElasticsearchResponse<T>> DoRequestAsync<T>(string method, string path, object data = null, IRequestParameters requestParameters = null)
6178
{
6279
return this.Transport.DoRequestAsync<T>(method, path, data, requestParameters);
6380
}

src/Elasticsearch.Net/IElasticsearchClient.Generated.cs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19439,6 +19439,27 @@ public interface IElasticsearchClient
1943919439
///</returns>
1944019440

1944119441
Task<ElasticsearchResponse<DynamicDictionary>> UpdateAsync(string index, string type, string id, object body, Func<UpdateRequestParameters, UpdateRequestParameters> requestParameters = null);
19442-
19442+
19443+
/// <summary>
19444+
/// Perform any request you want over the configured IConnection synchronously while taking advantage of the cluster failover.
19445+
/// </summary>
19446+
/// <typeparam name="T">The type representing the response JSON</typeparam>
19447+
/// <param name="method">the HTTP Method to use</param>
19448+
/// <param name="path">The path of the the url that you would like to hit</param>
19449+
/// <param name="data">The body of the request, string and byte[] are posted as is other types will be serialized to JSON</param>
19450+
/// <param name="requestParameters">Optionally configure request specific timeouts, headers</param>
19451+
/// <returns>An ElasticsearchResponse of T where T represents the JSON response body</returns>
19452+
ElasticsearchResponse<T> DoRequest<T>(string method, string path, object data = null, IRequestParameters requestParameters = null);
19453+
19454+
/// <summary>
19455+
/// Perform any request you want over the configured IConnection asynchronously while taking advantage of the cluster failover.
19456+
/// </summary>
19457+
/// <typeparam name="T">The type representing the response JSON</typeparam>
19458+
/// <param name="method">the HTTP Method to use</param>
19459+
/// <param name="path">The path of the the url that you would like to hit</param>
19460+
/// <param name="data">The body of the request, string and byte[] are posted as is other types will be serialized to JSON</param>
19461+
/// <param name="requestParameters">Optionally configure request specific timeouts, headers</param>
19462+
/// <returns>A task of ElasticsearchResponse of T where T represents the JSON response body</returns>
19463+
Task<ElasticsearchResponse<T>> DoRequestAsync<T>(string method, string path, object data = null, IRequestParameters requestParameters = null);
1944319464
}
1944419465
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
using System;
2+
using System.Linq;
3+
using System.Threading.Tasks;
4+
using Elasticsearch.Net;
5+
6+
namespace Nest
7+
{
8+
public partial class ElasticClient
9+
{
10+
/// <summary>
11+
/// Perform any request you want over the configured IConnection while taking advantage of the cluster failover.
12+
/// </summary>
13+
/// <typeparam name="T">The type representing the response JSON</typeparam>
14+
/// <param name="method">the HTTP Method to use</param>
15+
/// <param name="path">The path of the the url that you would like to hit</param>
16+
/// <param name="data">The body of the request, string and byte[] are posted as is other types will be serialized to JSON</param>
17+
/// <param name="requestParameters">Optionally configure request specific timeouts, headers</param>
18+
/// <returns>An ElasticsearchResponse of T where T represents the JSON response body</returns>
19+
public ElasticsearchResponse<T> DoRequest<T>(string method, string path, object data = null, IRequestParameters requestParameters = null)
20+
{
21+
return this.Raw.DoRequest<T>(method, path, data, requestParameters);
22+
}
23+
24+
/// <summary>
25+
/// Perform any request you want over the configured IConnection asynchronously while taking advantage of the cluster failover.
26+
/// </summary>
27+
/// <typeparam name="T">The type representing the response JSON</typeparam>
28+
/// <param name="method">the HTTP Method to use</param>
29+
/// <param name="path">The path of the the url that you would like to hit</param>
30+
/// <param name="data">The body of the request, string and byte[] are posted as is other types will be serialized to JSON</param>
31+
/// <param name="requestParameters">Optionally configure request specific timeouts, headers</param>
32+
/// <returns>A task of ElasticsearchResponse of T where T represents the JSON response body</returns>
33+
public Task<ElasticsearchResponse<T>> DoRequestAsync<T>(string method, string path, object data = null, IRequestParameters requestParameters = null)
34+
{
35+
return this.Raw.DoRequestAsync<T>(method, path, data, requestParameters);
36+
}
37+
38+
}
39+
}

src/Nest/ElasticClient.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ private static R CreateInvalidInstance<R>(IElasticsearchResponse response) where
111111
return r;
112112
}
113113

114-
internal Task<I> DispatchAsync<D, Q, R, I>(
114+
private Task<I> DispatchAsync<D, Q, R, I>(
115115
Func<D, D> selector
116116
, Func<ElasticsearchPathInfo<Q>, D, Task<ElasticsearchResponse<R>>> dispatch
117117
)

0 commit comments

Comments
 (0)