Skip to content

Commit f32f1a3

Browse files
committed
Fixed an edgecase where .Fields() in combination with .Types() on .Search() would cause the FieldSelection property on Hit<T> to be null
1 parent 54e1bf6 commit f32f1a3

File tree

18 files changed

+318
-62
lines changed

18 files changed

+318
-62
lines changed

build/build.fsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ let nugetPack = fun name ->
6969
CreateDir nugetOutDir
7070

7171
let dir = sprintf "%s/%s/" buildDir name
72-
let version = "1.0.0-alpha4"
72+
let version = "1.0.0-beta9"
7373
NuGetPack (fun p ->
7474
{p with
7575
Version = version

src/Elasticsearch.Net/Connection/InMemoryConnection.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,20 @@ namespace Elasticsearch.Net.Connection
99
{
1010
public class InMemoryConnection : HttpConnection
1111
{
12-
private readonly byte[] _fixedResultBytes = Encoding.UTF8.GetBytes("{ \"USING NEST IN MEMORY CONNECTION\" : null }");
12+
private byte[] _fixedResultBytes = Encoding.UTF8.GetBytes("{ \"USING NEST IN MEMORY CONNECTION\" : null }");
1313

1414
public InMemoryConnection(IConnectionConfigurationValues settings)
1515
: base(settings)
1616
{
1717

1818
}
1919

20+
public InMemoryConnection(IConnectionConfigurationValues settings, string fixedResult)
21+
: this (settings)
22+
{
23+
_fixedResultBytes = Encoding.UTF8.GetBytes(fixedResult);
24+
}
25+
2026
protected override ElasticsearchResponse<T> DoSynchronousRequest<T>(HttpWebRequest request, byte[] data = null, object deserializationState = null)
2127
{
2228
return this.ReturnConnectionStatus<T>(request, data, deserializationState);

src/Nest/Domain/Connection/ConnectionSettings.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,8 @@ string IConnectionSettingsValues.DefaultIndex
8888

8989
public ConnectionSettings(IConnectionPool uri, string defaultIndex) : base(uri)
9090
{
91-
defaultIndex.ThrowIfNullOrEmpty("defaultIndex");
92-
93-
this.SetDefaultIndex(defaultIndex);
91+
if (!defaultIndex.IsNullOrEmpty())
92+
this.SetDefaultIndex(defaultIndex);
9493

9594
this._defaultTypeNameInferrer = (t => t.Name.ToLower());
9695
this._defaultPropertyNameInferrer = (p => p.ToCamelCase());

src/Nest/Domain/FieldSelection.cs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ public interface IFieldSelection<out T>
1818
/// </summary>
1919
/// <typeparam name="K">The type to return the value as, remember that if your field is a string K should be string[]</typeparam>
2020
K FieldValue<K>(string path);
21+
22+
K[] FieldValue<TBindTo, K>(Expression<Func<TBindTo, object>> objectPath)
23+
where TBindTo : class;
2124

2225
}
2326

@@ -36,26 +39,28 @@ public FieldSelection(IConnectionSettingsValues settings, IDictionary<string, ob
3639
/// <summary>
3740
/// As of elasticsearch fields are always returned as an array. except for internal metadata values such as routing.
3841
/// </summary>
39-
public K[] FieldValue<K>(Expression<Func<T, K>> objectPath)
42+
/// <typeparam name="K">The type to return the value as, remember that if your field is a string K should be string[]</typeparam>
43+
public K FieldValue<K>(string path)
4044
{
41-
var path = this.Infer.PropertyPath(objectPath);
42-
return this.FieldValue<K[]>(path);
45+
return this.FieldArray<K>(path);
4346
}
4447

4548
/// <summary>
46-
/// As of elasticsearch fields are always returned as an array. except for internal metadata values such as routing.
49+
/// As of elasticsearch fields are always returned as an array.
50+
/// except for internal metadata values such as routing.
4751
/// </summary>
48-
public K[] FieldValue<K>(Expression<Func<T, object>> objectPath)
52+
public K[] FieldValue<TBindTo, K>(Expression<Func<TBindTo, object>> objectPath)
53+
where TBindTo : class
4954
{
5055
var path = this.Infer.PropertyPath(objectPath);
51-
return this.FieldValue<K[]>(path);
56+
return this.FieldArray<K[]>(path);
5257
}
5358

5459
/// <summary>
5560
/// As of elasticsearch fields are always returned as an array. except for internal metadata values such as routing.
5661
/// </summary>
5762
/// <typeparam name="K">The type to return the value as, remember that if your field is a string K should be string[]</typeparam>
58-
public K FieldValue<K>(string path)
63+
private K FieldArray<K>(string path)
5964
{
6065
object o;
6166
if (FieldValues.TryGetValue(path, out o))

src/Nest/Domain/Hit/MultiGetHit.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public class MultiGetHit<T> : IMultiGetHit<T>
2727
where T : class
2828
{
2929
//[JsonProperty(PropertyName = "fields")]
30-
public FieldSelection<T> FieldSelection { get; internal set; }
30+
public IFieldSelection<T> FieldSelection { get; internal set; }
3131

3232
[JsonProperty(PropertyName = "_source")]
3333
public T Source { get; internal set; }

src/Nest/Domain/Responses/GetAliasesResponse.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,17 @@ namespace Nest
55
{
66
public interface IGetAliasesResponse : IResponse
77
{
8-
IDictionary<string, IndexAliases> Indices { get; }
8+
IDictionary<string, IList<string>> Indices { get; }
99
}
1010

1111
public class GetAliasesResponse : BaseResponse, IGetAliasesResponse
1212
{
1313
public GetAliasesResponse()
1414
{
1515
this.IsValid = true;
16+
this.Indices = new Dictionary<string, IList<string>>();
1617
}
1718

18-
public IDictionary<string, IndexAliases> Indices { get; internal set; }
19+
public IDictionary<string, IList<string>> Indices { get; internal set; }
1920
}
2021
}

src/Nest/Domain/Responses/GetResponse.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,11 @@ public FieldSelection<T> Fields
7070
}
7171
}
7272

73-
public K[] FieldValue<K>(Expression<Func<T, object>> objectPath)
73+
public K[] FieldValue<TBindTo, K>(Expression<Func<TBindTo, object>> objectPath)
74+
where TBindTo : class
7475
{
7576
if (this.Fields == null) return default(K[]);
76-
return this.Fields.FieldValue<K>(objectPath);
77+
return this.Fields.FieldValue<TBindTo,K>(objectPath);
7778
}
7879

7980
public K FieldValue<K>(string path)

src/Nest/Domain/Responses/MultiGetResponse.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ public interface IMultiGetResponse : IResponse
1313
MultiGetHit<T> Get<T>(int id) where T : class;
1414
T Source<T>(string id) where T : class;
1515
T Source<T>(int id) where T : class;
16-
FieldSelection<T> GetFieldSelection<T>(string id) where T : class;
17-
FieldSelection<T> GetFieldSelection<T>(int id) where T : class;
16+
IFieldSelection<T> GetFieldSelection<T>(string id) where T : class;
17+
IFieldSelection<T> GetFieldSelection<T>(int id) where T : class;
1818
IEnumerable<T> SourceMany<T>(IEnumerable<string> ids) where T : class;
1919
IEnumerable<T> SourceMany<T>(IEnumerable<int> ids) where T : class;
2020
IEnumerable<IMultiGetHit<T>> GetMany<T>(IEnumerable<string> ids) where T : class;
@@ -58,6 +58,7 @@ public IEnumerable<T> SourceMany<T>(IEnumerable<string> ids) where T : class
5858
var docs = this.Documents.OfType<IMultiGetHit<T>>();
5959
return from d in docs
6060
join id in ids on d.Id equals id
61+
where d.Found
6162
select d.Source;
6263
}
6364
public IEnumerable<T> SourceMany<T>(IEnumerable<int> ids) where T : class
@@ -76,14 +77,14 @@ public IEnumerable<IMultiGetHit<T>> GetMany<T>(IEnumerable<int> ids) where T : c
7677
{
7778
return this.GetMany<T>(ids.Select(i=>i.ToString(CultureInfo.InvariantCulture)));
7879
}
79-
public FieldSelection<T> GetFieldSelection<T>(string id) where T : class
80+
public IFieldSelection<T> GetFieldSelection<T>(string id) where T : class
8081
{
8182
var multiHit = this.Get<T>(id);
8283
if (multiHit == null)
8384
return null;
8485
return multiHit.FieldSelection;
8586
}
86-
public FieldSelection<T> GetFieldSelection<T>(int id) where T : class
87+
public IFieldSelection<T> GetFieldSelection<T>(int id) where T : class
8788
{
8889
return this.GetFieldSelection<T>(id.ToString(CultureInfo.InvariantCulture));
8990
}

src/Nest/Domain/Responses/QueryResponse.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ public class QueryResponse<T> : BaseResponse, IQueryResponse<T> where T : class
3535
public QueryResponse()
3636
{
3737
this.IsValid = true;
38+
this.Aggregations = new Dictionary<string, IAggregation>();
39+
this.Facets = new Dictionary<string, Facet>();
3840
}
3941

4042
[JsonProperty(PropertyName = "_shards")]
@@ -101,7 +103,7 @@ public IEnumerable<T> Documents
101103
{
102104
if (this.HitsMetaData != null && this._documents == null)
103105
this._documents = this.HitsMetaData.Hits.Select(h => h.Source).ToList();
104-
return this._documents;
106+
return this._documents ?? Enumerable.Empty<T>();
105107
}
106108
}
107109

src/Nest/ElasticClient-Aliases.cs

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.IO;
34
using System.Linq;
45
using System.Threading.Tasks;
56
using Elasticsearch.Net;
67

78
namespace Nest
89
{
10+
using GetAliasesConverter = Func<IElasticsearchResponse, Stream, GetAliasesResponse>;
11+
using CrazyAliasesResponse = Dictionary<string, Dictionary<string, Dictionary<string, object>>>;
12+
913
public partial class ElasticClient
1014
{
1115
/// <inheritdoc />
@@ -31,7 +35,10 @@ public IGetAliasesResponse GetAliases(Func<GetAliasesDescriptor, GetAliasesDescr
3135
{
3236
return this.Dispatch<GetAliasesDescriptor, GetAliasesQueryString, GetAliasesResponse>(
3337
getAliasesDescriptor,
34-
(p, d) => this.RawDispatch.IndicesGetAliasDispatch<GetAliasesResponse>(p)
38+
(p, d) => this.RawDispatch.IndicesGetAliasDispatch<GetAliasesResponse>(
39+
p,
40+
new GetAliasesConverter(DeserializeGetAliasesResponse)
41+
)
3542
);
3643
}
3744

@@ -40,8 +47,43 @@ public Task<IGetAliasesResponse> GetAliasesAsync(Func<GetAliasesDescriptor, GetA
4047
{
4148
return this.DispatchAsync<GetAliasesDescriptor, GetAliasesQueryString, GetAliasesResponse, IGetAliasesResponse>(
4249
getAliasesDescriptor,
43-
(p, d) => this.RawDispatch.IndicesGetAliasDispatchAsync<GetAliasesResponse>(p)
50+
(p, d) => this.RawDispatch.IndicesGetAliasDispatchAsync<GetAliasesResponse>(
51+
p,
52+
new GetAliasesConverter(DeserializeGetAliasesResponse)
53+
)
4454
);
4555
}
56+
57+
/// <inheritdoc />
58+
private GetAliasesResponse DeserializeGetAliasesResponse(IElasticsearchResponse connectionStatus, Stream stream)
59+
{
60+
if (!connectionStatus.Success)
61+
return new GetAliasesResponse() {ConnectionStatus = connectionStatus, IsValid = false};
62+
63+
var dict = this.Serializer.DeserializeInternal<CrazyAliasesResponse>(stream);
64+
65+
var d = new Dictionary<string, IList<string>>();
66+
67+
foreach (var kv in dict)
68+
{
69+
var indexDict = kv.Key;
70+
var aliases = new List<string>();
71+
if (kv.Value != null && kv.Value.ContainsKey("aliases"))
72+
{
73+
var aliasDict = kv.Value["aliases"];
74+
if (aliasDict != null)
75+
aliases = aliasDict.Select(kva => kva.Key).ToList();
76+
}
77+
78+
d.Add(indexDict, aliases);
79+
}
80+
81+
return new GetAliasesResponse()
82+
{
83+
ConnectionStatus = connectionStatus,
84+
IsValid = true,
85+
Indices = d
86+
};
87+
}
4688
}
4789
}

0 commit comments

Comments
 (0)