diff --git a/docs/common-options/union/union.asciidoc b/docs/common-options/union/union.asciidoc new file mode 100644 index 00000000000..59c77b95a19 --- /dev/null +++ b/docs/common-options/union/union.asciidoc @@ -0,0 +1,95 @@ +:ref_current: https://www.elastic.co/guide/en/elasticsearch/reference/6.1 + +:github: https://github.com/elastic/elasticsearch-net + +:nuget: https://www.nuget.org/packages + +//// +IMPORTANT NOTE +============== +This file has been generated from https://github.com/elastic/elasticsearch-net/tree/master/src/Tests/CommonOptions/Union/Union.doc.cs. +If you wish to submit a PR for any spelling mistakes, typos or grammatical errors for this file, +please modify the original csharp file found at the link and submit the PR with that change. Thanks! +//// + +[[union]] +=== Union type + +Some API parameters within Elasticsearch can accept more than one JSON data structure, for example, source filtering on +a search request can accept + +* a `bool` value to disable `_source` retrieval + +* a `string` value representing a wildcard pattern to control what parts of `_source` to return + +* an array of `string` values representing multiple wildcard patterns to control what parts of `_source` to return + +* an `object` with `includes` and `excludes` properties that each accept an array of wildcard patterns to control +what parts of `_source` to include and exclude, respectively. + +That's a lot of different flexibility! NEST includes a `Union` type to make it easier to work with +these kinds of parameters, forming the union of two types, `TFirst` and `TSecond`. + +==== Implicit conversion + +The `Union` has implicit operators to convert from an instance of `TFirst` or `TSecond` to an +instance of `Union`. This is often the easiest way of construction an instance + +[source,csharp] +---- +Union sourceFilterFalse = false; + +Union sourceFilterInterface = new SourceFilter +{ + Includes = new [] { "foo.*" } +}; +---- + +==== Constructor + +Sometimes, the constructor of `Union` may be required in cases where the compiler is +unable to infer the correct implicit conversion + +[source,csharp] +---- +var sourceFilterTrue = new Union(true); + +var sourceFilterInterface = new Union(new SourceFilter +{ + Includes = new [] { "foo.*" } +}); +---- + +==== Match + +The `Match` method can be used to operate on the value encapsulated by the instance of `Union`. +Two delegates are passed; one to operate on a `TFirst` value and the other toe operate on a `TSecond` value. + +[source,csharp] +---- +sourceFilterTrue.Match( + b => b.Should().BeTrue(), + s => s.Should().BeNull()); + +sourceFilterInterface.Match( + b => b.Should().BeFalse(), + s => s.Should().NotBeNull()); +---- + +The delegates can also return a value + +[source,csharp] +---- +var serializedFilterTrue = sourceFilterTrue.Match( + b => serializer.SerializeToString(b), + s => null); + +serializedFilterTrue.Should().Be("true"); + +var serializedFilterInterface = sourceFilterTrue.Match( + b => null, + s => serializer.SerializeToString(s)); + +serializedFilterInterface.Should().Be("{\"includes\":[\"foo.*\"]}"); +---- + diff --git a/docs/high-level.asciidoc b/docs/high-level.asciidoc index 9c816dedcce..ff5d80dffc8 100644 --- a/docs/high-level.asciidoc +++ b/docs/high-level.asciidoc @@ -49,6 +49,8 @@ As well as a number of types for working with * <> +* <> + And features such as * <> @@ -258,9 +260,13 @@ NEST has a number of types for working with Elasticsearch conventions for * <> +* <> + include::common-options/time-unit/time-units.asciidoc[] include::common-options/distance-unit/distance-units.asciidoc[] include::common-options/date-math/date-math-expressions.asciidoc[] +include::common-options/union/union.asciidoc[] + diff --git a/src/Nest/Aggregations/Bucket/Terms/TermsExclude.cs b/src/Nest/Aggregations/Bucket/Terms/TermsExclude.cs index be04aed3bf6..08a4d530eee 100644 --- a/src/Nest/Aggregations/Bucket/Terms/TermsExclude.cs +++ b/src/Nest/Aggregations/Bucket/Terms/TermsExclude.cs @@ -3,23 +3,36 @@ namespace Nest { + /// + /// Filters which terms to exclude from the response + /// [JsonConverter(typeof(TermsExcludeJsonConverter))] public class TermsExclude { + /// + /// The regular expression pattern to determine terms to exclude from the response + /// [JsonIgnore] public string Pattern { get; set; } + /// + /// Collection of terms to exclude from the response + /// [JsonIgnore] public IEnumerable Values { get; set; } - public TermsExclude(string pattern) - { - Pattern = pattern; - } + /// + /// Creates an instance of that uses a regular expression pattern + /// to determine the terms to exclude from the response + /// + /// The regular expression pattern + public TermsExclude(string pattern) => Pattern = pattern; - public TermsExclude(IEnumerable values) - { - Values = values; - } + /// + /// Creates an instance of that uses a collection of terms + /// to exclude from the response + /// + /// The exact terms to exclude + public TermsExclude(IEnumerable values) => Values = values; } -} \ No newline at end of file +} diff --git a/src/Nest/Aggregations/Bucket/Terms/TermsInclude.cs b/src/Nest/Aggregations/Bucket/Terms/TermsInclude.cs index 4f8686d77be..b036181c26b 100644 --- a/src/Nest/Aggregations/Bucket/Terms/TermsInclude.cs +++ b/src/Nest/Aggregations/Bucket/Terms/TermsInclude.cs @@ -4,12 +4,21 @@ namespace Nest { + /// + /// Filters which terms to include in the response + /// [JsonConverter(typeof(TermsIncludeJsonConverter))] public class TermsInclude { + /// + /// The regular expression pattern to determine terms to include in the response + /// [JsonIgnore] public string Pattern { get; set; } + /// + /// Collection of terms to include in the response + /// [JsonIgnore] public IEnumerable Values { get; set; } @@ -25,16 +34,26 @@ public class TermsInclude [JsonProperty("num_partitions")] public long? NumberOfPartitions { get; set; } - public TermsInclude(string pattern) - { - Pattern = pattern; - } + /// + /// Creates an instance of that uses a regular expression pattern + /// to determine the terms to include in the response + /// + /// The regular expression pattern + public TermsInclude(string pattern) => Pattern = pattern; - public TermsInclude(IEnumerable values) - { - Values = values; - } + /// + /// Creates an instance of that uses a collection of terms + /// to include in the response + /// + /// The exact terms to include + public TermsInclude(IEnumerable values) => Values = values; + /// + /// Creates an instance of that partitions the terms into a number of + /// partitions to receive in multiple requests. Used to process many unique terms + /// + /// The 0-based partition number for this request + /// The total number of partitions public TermsInclude(long partition, long numberOfPartitions) { Partition = partition; diff --git a/src/Nest/CommonAbstractions/Union/Union.cs b/src/Nest/CommonAbstractions/Union/Union.cs index e61c4de0b50..de74bcda625 100644 --- a/src/Nest/CommonAbstractions/Union/Union.cs +++ b/src/Nest/CommonAbstractions/Union/Union.cs @@ -3,6 +3,12 @@ namespace Nest { + /// + /// Represents the union of two types, and . Used + /// in scenarios where an Elasticsearch API may accept more than one different input data structure. + /// + /// The first type + /// The second type [JsonConverter(typeof(UnionJsonConverter))] public class Union { @@ -10,9 +16,23 @@ public class Union internal readonly TSecond Item2; internal readonly int _tag; + /// + /// Creates an new instance of that encapsulates value + /// + /// The value to encapsulate public Union(TFirst item) { Item1 = item; _tag = 0; } + + /// + /// Creates an new instance of that encapsulates value + /// + /// The value to encapsulate public Union(TSecond item) { Item2 = item; _tag = 1; } + /// + /// Runs an delegate against the encapsulated value + /// + /// The delegate to run when this instance encapsulates an instance of + /// The delegate to run when this instance encapsulates an instance of public void Match(Action first, Action second) { switch (_tag) @@ -26,6 +46,12 @@ public void Match(Action first, Action second) default: throw new Exception($"Unrecognized tag value: {_tag}"); } } + + /// + /// Runs a delegate against the encapsulated value + /// + /// The delegate to run when this instance encapsulates an instance of + /// The delegate to run when this instance encapsulates an instance of public T Match(Func first, Func second) { switch (_tag) diff --git a/src/Nest/CommonAbstractions/Union/UnionJsonConverter.cs b/src/Nest/CommonAbstractions/Union/UnionJsonConverter.cs index 08992030a09..d9768cdd3eb 100644 --- a/src/Nest/CommonAbstractions/Union/UnionJsonConverter.cs +++ b/src/Nest/CommonAbstractions/Union/UnionJsonConverter.cs @@ -15,8 +15,7 @@ internal class UnionJsonConverter : JsonConverter public static UnionJsonConverterBase CreateConverter(Type t) { - UnionJsonConverterBase conversion; - if (KnownTypes.TryGetValue(t, out conversion)) + if (KnownTypes.TryGetValue(t, out var conversion)) return conversion; var genericArguments = t.GetTypeInfo().GenericTypeArguments; @@ -55,9 +54,11 @@ public bool TryRead(JsonReader reader, JsonSerializer serializer, out T v) v = serializer.Deserialize(reader); return true; } - catch {} - v= default(T); - return false; + catch + { + v = default(T); + return false; + } } public abstract void WriteJson(JsonWriter writer, object v, JsonSerializer serializer); diff --git a/src/Nest/Search/Search/SourceFiltering/SourceFilter.cs b/src/Nest/Search/Search/SourceFiltering/SourceFilter.cs index 51fce9e800a..7b85b566dba 100644 --- a/src/Nest/Search/Search/SourceFiltering/SourceFilter.cs +++ b/src/Nest/Search/Search/SourceFiltering/SourceFilter.cs @@ -29,7 +29,6 @@ public class SourceFilterDescriptor : DescriptorBase Includes(Func, IPromise> fields) => Assign(a => a.Includes = fields?.Invoke(new FieldsDescriptor())?.Value); diff --git a/src/Tests/CommonOptions/Union/Union.doc.cs b/src/Tests/CommonOptions/Union/Union.doc.cs new file mode 100644 index 00000000000..440d6e786ad --- /dev/null +++ b/src/Tests/CommonOptions/Union/Union.doc.cs @@ -0,0 +1,98 @@ +using Elasticsearch.Net; +using FluentAssertions; +using Nest; +using Newtonsoft.Json; +using Tests.Framework; + +namespace Tests.CommonOptions.Union +{ + /**[[union]] + * === Union type + * Some API parameters within Elasticsearch can accept more than one JSON data structure, for example, source filtering on + * a search request can accept + * + * - a `bool` value to disable `_source` retrieval + * - a `string` value representing a wildcard pattern to control what parts of `_source` to return + * - an array of `string` values representing multiple wildcard patterns to control what parts of `_source` to return + * - an `object` with `includes` and `excludes` properties that each accept an array of wildcard patterns to control + * what parts of `_source` to include and exclude, respectively. + * + * That's a lot of different flexibility! NEST includes a `Union` type to make it easier to work with + * these kinds of parameters, forming the union of two types, `TFirst` and `TSecond`. + */ + public class Union + { + private IElasticsearchSerializer serializer = TestClient.DefaultInMemoryClient.RequestResponseSerializer; + + /** + * ==== Implicit conversion + * + * The `Union` has implicit operators to convert from an instance of `TFirst` or `TSecond` to an + * instance of `Union`. This is often the easiest way of construction an instance + */ + public void ImplicitConversion() + { + Union sourceFilterFalse = false; + + Union sourceFilterInterface = new SourceFilter + { + Includes = new [] { "foo.*" } + }; + + // hide + sourceFilterFalse.Match( + b => b.Should().BeFalse(), + s => s.Should().BeNull()); + + // hide + sourceFilterInterface.Match( + b => b.Should().BeFalse(), + s => s.Should().NotBeNull()); + } + + /** + * ==== Constructor + * + * Sometimes, the constructor of `Union` may be required in cases where the compiler is + * unable to infer the correct implicit conversion + */ + public void Constructor() + { + var sourceFilterTrue = new Union(true); + + var sourceFilterInterface = new Union(new SourceFilter + { + Includes = new [] { "foo.*" } + }); + + /** + * ==== Match + * + * The `Match` method can be used to operate on the value encapsulated by the instance of `Union`. + * Two delegates are passed; one to operate on a `TFirst` value and the other toe operate on a `TSecond` value. + */ + sourceFilterTrue.Match( + b => b.Should().BeTrue(), + s => s.Should().BeNull()); + + sourceFilterInterface.Match( + b => b.Should().BeFalse(), + s => s.Should().NotBeNull()); + + /** + * The delegates can also return a value + */ + var serializedFilterTrue = sourceFilterTrue.Match( + b => serializer.SerializeToString(b), + s => null); + + serializedFilterTrue.Should().Be("true"); + + var serializedFilterInterface = sourceFilterTrue.Match( + b => null, + s => serializer.SerializeToString(s)); + + serializedFilterInterface.Should().Be("{\"includes\":[\"foo.*\"]}"); + } + } +} diff --git a/src/Tests/high-level.asciidoc b/src/Tests/high-level.asciidoc index b75af2eabb4..c0fe16a29a9 100644 --- a/src/Tests/high-level.asciidoc +++ b/src/Tests/high-level.asciidoc @@ -33,6 +33,7 @@ As well as a number of types for working with - <> - <> - <> +- <> And features such as @@ -176,7 +177,9 @@ NEST has a number of types for working with Elasticsearch conventions for - <> - <> - <> +- <> include::common-options/time-unit/time-units.asciidoc[] include::common-options/distance-unit/distance-units.asciidoc[] -include::common-options/date-math/date-math-expressions.asciidoc[] \ No newline at end of file +include::common-options/date-math/date-math-expressions.asciidoc[] +include::common-options/union/union.asciidoc[] \ No newline at end of file