Skip to content

Commit 3e5568a

Browse files
committed
Merge branch 'fix/2.x-sourcefilter' into 2.x
2 parents 760bc00 + 5a798e2 commit 3e5568a

File tree

9 files changed

+104
-33
lines changed

9 files changed

+104
-33
lines changed

src/Nest/Aggregations/Metric/TopHits/TopHitsAggregation.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ public TopHitsAggregationDescriptor<T> Sort(Func<SortFieldDescriptor<T>, IFieldS
9191
});
9292

9393
public TopHitsAggregationDescriptor<T> Source(bool include = true) =>
94-
Assign(a => a.Source = !include ? SourceFilter.ExcludeAll : null);
94+
Assign(a => a.Source = new SourceFilter { Disable = !include });
9595

9696
public TopHitsAggregationDescriptor<T> Source(Func<SourceFilterDescriptor<T>, ISourceFilter> sourceSelector) =>
9797
Assign(a => a.Source = sourceSelector?.Invoke(new SourceFilterDescriptor<T>()));

src/Nest/CommonAbstractions/Infer/Fields/Fields.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ string IUrlParameter.GetString(IConnectionConfigurationValues settings) =>
2020

2121
public static implicit operator Fields(string[] fields) => new Fields(fields.Select(f => (Field)f));
2222

23+
public static implicit operator Fields(string field) => new Fields(new[] { (Field)field });
24+
2325
public static implicit operator Fields(Expression[] fields) => new Fields(fields.Select(f => (Field)f));
2426

2527
public static implicit operator Fields(Field[] fields) => new Fields(fields);

src/Nest/Search/Search/InnerHits/GlobalInnerHit.cs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,10 @@ public class GlobalInnerHitDescriptor<T> : DescriptorBase<GlobalInnerHitDescript
3838
IList<Field> IInnerHits.FielddataFields { get; set; }
3939
IScriptFields IInnerHits.ScriptFields { get; set; }
4040

41-
public GlobalInnerHitDescriptor<T> Query(Func<QueryContainerDescriptor<T>, QueryContainer> querySelector) =>
41+
public GlobalInnerHitDescriptor<T> Query(Func<QueryContainerDescriptor<T>, QueryContainer> querySelector) =>
4242
Assign(a => a.Query = querySelector?.Invoke(new QueryContainerDescriptor<T>()));
43-
44-
public GlobalInnerHitDescriptor<T> InnerHits(Func<NamedInnerHitsDescriptor<T>, IPromise<INamedInnerHits>> selector) =>
43+
44+
public GlobalInnerHitDescriptor<T> InnerHits(Func<NamedInnerHitsDescriptor<T>, IPromise<INamedInnerHits>> selector) =>
4545
Assign(a => a.InnerHits = selector?.Invoke(new NamedInnerHitsDescriptor<T>())?.Value);
4646

4747
public GlobalInnerHitDescriptor<T> From(int? from) => Assign(a => a.From = from);
@@ -52,7 +52,7 @@ public GlobalInnerHitDescriptor<T> InnerHits(Func<NamedInnerHitsDescriptor<T>, I
5252

5353
public GlobalInnerHitDescriptor<T> FielddataFields(params string[] fielddataFields) =>
5454
Assign(a => a.FielddataFields = fielddataFields?.Select(f => (Field) f).ToListOrNullIfEmpty());
55-
55+
5656
public GlobalInnerHitDescriptor<T> FielddataFields(params Expression<Func<T, object>>[] fielddataFields) =>
5757
Assign(a => a.FielddataFields = fielddataFields?.Select(f => (Field) f).ToListOrNullIfEmpty());
5858

@@ -63,17 +63,17 @@ public GlobalInnerHitDescriptor<T> FielddataFields(params Expression<Func<T, obj
6363
public GlobalInnerHitDescriptor<T> Sort(Func<SortDescriptor<T>, IPromise<IList<ISort>>> sortSelector) => Assign(a => a.Sort = sortSelector?.Invoke(new SortDescriptor<T>())?.Value);
6464

6565
/// <summary>
66-
/// Allow to highlight search results on one or more fields. The implementation uses the either lucene fast-vector-highlighter or highlighter.
66+
/// Allow to highlight search results on one or more fields. The implementation uses the either lucene fast-vector-highlighter or highlighter.
6767
/// </summary>
6868
public GlobalInnerHitDescriptor<T> Highlight(Func<HighlightDescriptor<T>, IHighlight> highlightSelector) =>
6969
Assign(a => a.Highlight = highlightSelector?.Invoke(new HighlightDescriptor<T>()));
70-
71-
public GlobalInnerHitDescriptor<T> Source(bool include = true)=> Assign(a => a.Source = !include ? SourceFilter.ExcludeAll : null);
72-
70+
71+
public GlobalInnerHitDescriptor<T> Source(bool include = true) => Assign(a => a.Source = new SourceFilter { Disable = !include });
72+
7373
public GlobalInnerHitDescriptor<T> Source(Func<SourceFilterDescriptor<T>, ISourceFilter> sourceSelector) =>
7474
Assign(a => a.Source = sourceSelector?.Invoke(new SourceFilterDescriptor<T>()));
7575

76-
public GlobalInnerHitDescriptor<T> ScriptFields(Func<ScriptFieldsDescriptor, IPromise<IScriptFields>> selector) =>
76+
public GlobalInnerHitDescriptor<T> ScriptFields(Func<ScriptFieldsDescriptor, IPromise<IScriptFields>> selector) =>
7777
Assign(a => a.ScriptFields = selector?.Invoke(new ScriptFieldsDescriptor())?.Value);
7878
}
79-
}
79+
}

src/Nest/Search/Search/InnerHits/InnerHits.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,18 +96,18 @@ public InnerHitsDescriptor<T> FielddataFields(params Expression<Func<T, object>>
9696
public InnerHitsDescriptor<T> Sort(Func<SortDescriptor<T>, IPromise<IList<ISort>>> sortSelector) => Assign(a => a.Sort = sortSelector?.Invoke(new SortDescriptor<T>())?.Value);
9797

9898
/// <summary>
99-
/// Allow to highlight search results on one or more fields. The implementation uses the either lucene fast-vector-highlighter or highlighter.
99+
/// Allow to highlight search results on one or more fields. The implementation uses the either lucene fast-vector-highlighter or highlighter.
100100
/// </summary>
101101
public InnerHitsDescriptor<T> Highlight(Func<HighlightDescriptor<T>, IHighlight> highlightSelector) =>
102102
Assign(a => a.Highlight = highlightSelector?.Invoke(new HighlightDescriptor<T>()));
103103

104104
//TODO map source of union bool/SourceFileter
105-
public InnerHitsDescriptor<T> Source(bool include = true) => Assign(a => a.Source = !include ? SourceFilter.ExcludeAll : null);
105+
public InnerHitsDescriptor<T> Source(bool include = true) => Assign(a => a.Source = new SourceFilter { Disable = !include });
106106

107107
public InnerHitsDescriptor<T> Source(Func<SourceFilterDescriptor<T>, ISourceFilter> sourceSelector) =>
108108
Assign(a => a.Source = sourceSelector?.Invoke(new SourceFilterDescriptor<T>()));
109109

110-
public InnerHitsDescriptor<T> ScriptFields(Func<ScriptFieldsDescriptor, IPromise<IScriptFields>> selector) =>
110+
public InnerHitsDescriptor<T> ScriptFields(Func<ScriptFieldsDescriptor, IPromise<IScriptFields>> selector) =>
111111
Assign(a => a.ScriptFields = selector?.Invoke(new ScriptFieldsDescriptor())?.Value);
112112
}
113113
}

src/Nest/Search/Search/SearchRequest.cs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@ public partial interface ISearchRequest : ICovariantSearchRequest
6464
IScriptFields ScriptFields { get; set; }
6565

6666
[JsonProperty(PropertyName = "_source")]
67-
[JsonConverter(typeof(ReadAsTypeJsonConverter<SourceFilter>))]
6867
ISourceFilter Source { get; set; }
6968

7069
[JsonProperty(PropertyName = "aggs")]
@@ -224,7 +223,7 @@ public partial class SearchDescriptor<T> where T : class
224223
public SearchDescriptor<T> Aggregations(Func<AggregationContainerDescriptor<T>, IAggregationContainer> aggregationsSelector) =>
225224
Assign(a => a.Aggregations = aggregationsSelector(new AggregationContainerDescriptor<T>())?.Aggregations);
226225

227-
public SearchDescriptor<T> Source(bool include = true) => Assign(a => a.Source = !include ? SourceFilter.ExcludeAll : null);
226+
public SearchDescriptor<T> Source(bool include = true) => Assign(a => a.Source = new SourceFilter { Disable = !include });
228227

229228
public SearchDescriptor<T> Source(Func<SourceFilterDescriptor<T>, ISourceFilter> sourceSelector) =>
230229
Assign(a => a.Source = sourceSelector?.Invoke(new SourceFilterDescriptor<T>()));
@@ -416,8 +415,8 @@ public SearchDescriptor<T> Highlight(Func<HighlightDescriptor<T>, IHighlight> hi
416415
public SearchDescriptor<T> Rescore(Func<RescoreDescriptor<T>, IRescore> rescoreSelector) =>
417416
Assign(a =>
418417
{
419-
a.Rescore = a.Rescore != null
420-
? new MultiRescore { a.Rescore, rescoreSelector?.Invoke(new RescoreDescriptor<T>()) }
418+
a.Rescore = a.Rescore != null
419+
? new MultiRescore { a.Rescore, rescoreSelector?.Invoke(new RescoreDescriptor<T>()) }
421420
: rescoreSelector?.Invoke(new RescoreDescriptor<T>());
422421
});
423422

src/Nest/Search/Search/SourceFiltering/SourceFilter.cs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ public interface ISourceFilter
1111

1212
[JsonProperty("exclude")]
1313
Fields Exclude { get; set; }
14+
15+
[JsonIgnore]
16+
bool Disable { get; set; }
1417
}
1518

1619
public class SourceFilter : ISourceFilter
@@ -20,6 +23,8 @@ public class SourceFilter : ISourceFilter
2023

2124
public Fields Include { get; set; }
2225
public Fields Exclude { get; set; }
26+
27+
public bool Disable { get; set; }
2328
}
2429

2530
public class SourceFilterDescriptor<T> : DescriptorBase<SourceFilterDescriptor<T>, ISourceFilter>, ISourceFilter
@@ -29,11 +34,19 @@ public class SourceFilterDescriptor<T> : DescriptorBase<SourceFilterDescriptor<T
2934

3035
Fields ISourceFilter.Exclude { get; set; }
3136

32-
public SourceFilterDescriptor<T> Include(Func<FieldsDescriptor<T>, IPromise<Fields>> fields) =>
37+
bool ISourceFilter.Disable { get; set; }
38+
39+
40+
public SourceFilterDescriptor<T> Include(Func<FieldsDescriptor<T>, IPromise<Fields>> fields) =>
3341
Assign(a => a.Include = fields?.Invoke(new FieldsDescriptor<T>())?.Value);
3442

35-
public SourceFilterDescriptor<T> Exclude(Func<FieldsDescriptor<T>, IPromise<Fields>> fields) =>
43+
public SourceFilterDescriptor<T> IncludeAll() => Assign(a => a.Include = new[] { "*" });
44+
45+
public SourceFilterDescriptor<T> Exclude(Func<FieldsDescriptor<T>, IPromise<Fields>> fields) =>
3646
Assign(a => a.Exclude = fields?.Invoke(new FieldsDescriptor<T>())?.Value);
3747

48+
public SourceFilterDescriptor<T> ExcludeAll() => Assign(a => a.Exclude = new[] { "*" });
49+
50+
public SourceFilterDescriptor<T> Disable(bool disable = true) => Assign(a => a.Disable = disable);
3851
}
3952
}

src/Nest/Search/Search/SourceFiltering/SourceFilterJsonConverter.cs

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,25 +7,48 @@ namespace Nest
77
public class SourceFilterJsonConverter : JsonConverter
88
{
99
public override bool CanRead => true;
10-
public override bool CanWrite => false;
10+
public override bool CanWrite => true;
1111
public override bool CanConvert(Type objectType) => true;
1212

1313
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
1414
{
15+
var filter = value as ISourceFilter;
16+
if (filter == null)
17+
return;
18+
if (filter.Disable)
19+
writer.WriteValue(false);
20+
else
21+
{
22+
if (filter.Include == null && filter.Exclude == null)
23+
return;
24+
25+
writer.WriteStartObject();
26+
if (filter.Include != null)
27+
{
28+
writer.WritePropertyName("include");
29+
serializer.Serialize(writer, filter.Include);
30+
}
31+
if (filter.Exclude != null)
32+
{
33+
writer.WritePropertyName("exclude");
34+
serializer.Serialize(writer, filter.Exclude);
35+
}
36+
writer.WriteEndObject();
37+
}
1538
}
1639

1740
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
1841
{
1942
if (reader.TokenType == JsonToken.Null) return null;
2043

21-
var filter = new SourceFilter();
44+
var filter = new SourceFilter();
2245
switch (reader.TokenType)
2346
{
2447
case JsonToken.Boolean:
25-
filter.Exclude = new[] { "*" };
48+
filter.Disable = !(bool)reader.Value;
2649
break;
2750
case JsonToken.String:
28-
filter.Include = new [] { (string)reader.Value };
51+
filter.Include = new[] { (string)reader.Value };
2952
break;
3053
case JsonToken.StartArray:
3154
var include = new List<string>();
@@ -41,4 +64,4 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist
4164
return filter;
4265
}
4366
}
44-
}
67+
}

src/Tests/Search/Request/SourceFilteringUsageTests.cs

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,17 @@ public SourceFilteringUsageTests(ReadOnlyCluster cluster, EndpointUsage usage) :
2424
{
2525
_source = new
2626
{
27-
include = new[] { "name", "startedOn" }
27+
include = new[] { "*" },
28+
exclude = new [] { "description" }
2829
}
2930
};
3031

3132
protected override Func<SearchDescriptor<Project>, ISearchRequest> Fluent => s => s
32-
.Source(so => so
33-
.Include(f => f
33+
.Source(src => src
34+
.IncludeAll()
35+
.Exclude(e => e
3436
.Fields(
35-
p => p.Name,
36-
p => p.StartedOn
37+
p => p.Description
3738
)
3839
)
3940
);
@@ -43,7 +44,8 @@ public SourceFilteringUsageTests(ReadOnlyCluster cluster, EndpointUsage usage) :
4344
{
4445
Source = new SourceFilter
4546
{
46-
Include = Fields<Project>(p => p.Name, prop => prop.StartedOn)
47+
Include = "*",
48+
Exclude = Fields<Project>(p => p.Description)
4749
}
4850
};
4951

@@ -60,6 +62,36 @@ protected override void ExpectResponse(ISearchResponse<Project> response)
6062
}
6163
}
6264

65+
public class SourceFilteringDisabledUsageTests : SearchUsageTestBase
66+
{
67+
public SourceFilteringDisabledUsageTests(ReadOnlyCluster cluster, EndpointUsage usage) : base(cluster, usage) { }
68+
69+
protected override object ExpectJson =>
70+
new
71+
{
72+
_source = false
73+
};
74+
75+
protected override Func<SearchDescriptor<Project>, ISearchRequest> Fluent => s => s
76+
.Source(src => src.Disable());
77+
78+
protected override SearchRequest<Project> Initializer =>
79+
new SearchRequest<Project>
80+
{
81+
Source = new SourceFilter
82+
{
83+
Disable = true
84+
}
85+
};
86+
87+
protected override void ExpectResponse(ISearchResponse<Project> response)
88+
{
89+
response.ShouldBeValid();
90+
foreach (var hit in response.Hits)
91+
hit.Source.Should().BeNull();
92+
}
93+
}
94+
6395
//hide
6496
public class SourceFilteringSerializationTests : SerializationTestBase
6597
{
@@ -75,7 +107,9 @@ public void CanDeserializeBoolean()
75107
var o = base.Deserialize<WithSourceFilterProperty>("{ \"_source\": false }");
76108
o.Should().NotBeNull();
77109
o.SourceFilter.Should().NotBeNull();
78-
o.SourceFilter.Exclude.Should().Contain("*");
110+
o.SourceFilter.Exclude.Should().BeNull();
111+
o.SourceFilter.Include.Should().BeNull();
112+
o.SourceFilter.Disable.Should().BeTrue();
79113
}
80114

81115
[U]

src/Tests/tests.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# mode either u (unit test), i (integration test) or m (mixed mode)
2-
mode: m
2+
mode: u
33
# the elasticsearch version that should be started
44
elasticsearch_version: 2.3.5
55
# whether we want to forcefully reseed on the node, if you are starting the tests with a node already running

0 commit comments

Comments
 (0)