diff --git a/Directory.Build.props b/Directory.Build.props index 008d7f4e..13e3103d 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -23,7 +23,7 @@ true true true - $(NoWarn);CS1591 + $(NoWarn);CS1591;NRS003 $([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::get_Windows()))) diff --git a/Directory.Packages.props b/Directory.Packages.props index b61ed977..31c1d6bc 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -12,7 +12,7 @@ - + diff --git a/docs/exp/NRS003.md b/docs/exp/NRS003.md new file mode 100644 index 00000000..c9db3317 --- /dev/null +++ b/docs/exp/NRS003.md @@ -0,0 +1,33 @@ +`REDUCE COLLECT` is gated behind the server's *unstable features* flag; the feature and its API may be subject to change. + +*COLLECT* is an `FT.AGGREGATE` reducer that gathers per-document projections within a `GROUPBY` group and returns them +as an array of per-entry maps under the reducer alias, optionally sorted and bounded. + +The server does not expose it by default: it must be enabled explicitly, for example via + +``` +CONFIG SET search-enable-unstable-features yes +``` + +In a cluster the coordinator fans the query out to every shard, so the flag must be enabled on all nodes rather than +only the one a given connection happens to route to. Without it, the server replies with an error. + +The corresponding library feature must also be considered subject to change: + +1. Existing bindings may cease working correctly if the underlying server API changes. +2. Changes to the server API may require changes to the library API, manifesting in either/both of build-time + or run-time breaks. + +Because the server itself still classes this as an unstable feature, such changes are rather more likely here than for +a feature that has simply not been out for long. If you acknowledge this, you can suppress this warning by adding the +following to your `csproj` file: + +```xml +$(NoWarn);NRS003 +``` + +or more granularly / locally in C#: + +```c# +#pragma warning disable NRS003 +``` diff --git a/src/NRedisStack/Experiments.cs b/src/NRedisStack/Experiments.cs index eee7520f..0c5e266f 100644 --- a/src/NRedisStack/Experiments.cs +++ b/src/NRedisStack/Experiments.cs @@ -9,6 +9,8 @@ namespace NRedisStack // NRS002 - Redis 8.8 multi-aggregate time-series internal static class Experiments { + public const string SearchCollect = "NRS003"; + // {0} is substituted with the diagnostic id, e.g. NRS042 -> https://redis.github.io/NRedisStack/exp/NRS042 public const string UrlFormat = "https://redis.github.io/NRedisStack/exp/{0}"; } diff --git a/src/NRedisStack/PublicAPI/PublicAPI.Shipped.txt b/src/NRedisStack/PublicAPI/PublicAPI.Shipped.txt index 5085b70e..8f015a70 100644 --- a/src/NRedisStack/PublicAPI/PublicAPI.Shipped.txt +++ b/src/NRedisStack/PublicAPI/PublicAPI.Shipped.txt @@ -1670,13 +1670,13 @@ NRedisStack.ISearchCommandsAsync.AliasListAsync(string! index) -> System.Threadi NRedisStack.SearchCommands.AliasList(string! index) -> StackExchange.Redis.RedisResult![]! NRedisStack.SearchCommandsAsync.AliasListAsync(string! index) -> System.Threading.Tasks.Task! static NRedisStack.SearchCommandBuilder.AliasList(string! index) -> NRedisStack.RedisStackCommands.SerializedCommand! -NRedisStack.Search.Aggregation.CollectReducer -override NRedisStack.Search.Aggregation.CollectReducer.Name.get -> string! -NRedisStack.Search.Aggregation.CollectReducer.Fields(params string![]! fields) -> NRedisStack.Search.Aggregation.CollectReducer! -NRedisStack.Search.Aggregation.CollectReducer.FieldsAll() -> NRedisStack.Search.Aggregation.CollectReducer! -NRedisStack.Search.Aggregation.CollectReducer.SortBy(params NRedisStack.Search.Aggregation.SortedField![]! fields) -> NRedisStack.Search.Aggregation.CollectReducer! -NRedisStack.Search.Aggregation.CollectReducer.SortByAsc(string! field) -> NRedisStack.Search.Aggregation.CollectReducer! -NRedisStack.Search.Aggregation.CollectReducer.SortByDesc(string! field) -> NRedisStack.Search.Aggregation.CollectReducer! -NRedisStack.Search.Aggregation.CollectReducer.Limit(int count) -> NRedisStack.Search.Aggregation.CollectReducer! -NRedisStack.Search.Aggregation.CollectReducer.Limit(int offset, int count) -> NRedisStack.Search.Aggregation.CollectReducer! -static NRedisStack.Search.Aggregation.Reducers.Collect() -> NRedisStack.Search.Aggregation.CollectReducer! +[NRS003]NRedisStack.Search.Aggregation.CollectReducer +[NRS003]override NRedisStack.Search.Aggregation.CollectReducer.Name.get -> string! +[NRS003]NRedisStack.Search.Aggregation.CollectReducer.Fields(params string![]! fields) -> NRedisStack.Search.Aggregation.CollectReducer! +[NRS003]NRedisStack.Search.Aggregation.CollectReducer.FieldsAll() -> NRedisStack.Search.Aggregation.CollectReducer! +[NRS003]NRedisStack.Search.Aggregation.CollectReducer.SortBy(params NRedisStack.Search.Aggregation.SortedField![]! fields) -> NRedisStack.Search.Aggregation.CollectReducer! +[NRS003]NRedisStack.Search.Aggregation.CollectReducer.SortByAsc(string! field) -> NRedisStack.Search.Aggregation.CollectReducer! +[NRS003]NRedisStack.Search.Aggregation.CollectReducer.SortByDesc(string! field) -> NRedisStack.Search.Aggregation.CollectReducer! +[NRS003]NRedisStack.Search.Aggregation.CollectReducer.Limit(int count) -> NRedisStack.Search.Aggregation.CollectReducer! +[NRS003]NRedisStack.Search.Aggregation.CollectReducer.Limit(int offset, int count) -> NRedisStack.Search.Aggregation.CollectReducer! +[NRS003]static NRedisStack.Search.Aggregation.Reducers.Collect() -> NRedisStack.Search.Aggregation.CollectReducer! diff --git a/src/NRedisStack/Search/CollectReducer.cs b/src/NRedisStack/Search/CollectReducer.cs index 878697cc..08b9d1bb 100644 --- a/src/NRedisStack/Search/CollectReducer.cs +++ b/src/NRedisStack/Search/CollectReducer.cs @@ -1,4 +1,5 @@ -using NRedisStack.Search.Literals; +using System.Diagnostics.CodeAnalysis; +using NRedisStack.Search.Literals; namespace NRedisStack.Search.Aggregation; @@ -33,6 +34,7 @@ namespace NRedisStack.Search.Aggregation; /// /// /// +[Experimental(Experiments.SearchCollect, UrlFormat = Experiments.UrlFormat)] public sealed class CollectReducer : Reducer { private bool _allFields = false; diff --git a/src/NRedisStack/Search/Reducers.cs b/src/NRedisStack/Search/Reducers.cs index d8a20e23..b348d032 100644 --- a/src/NRedisStack/Search/Reducers.cs +++ b/src/NRedisStack/Search/Reducers.cs @@ -1,4 +1,6 @@ -namespace NRedisStack.Search.Aggregation; +using System.Diagnostics.CodeAnalysis; + +namespace NRedisStack.Search.Aggregation; public static class Reducers { @@ -92,6 +94,7 @@ protected override void AddOwnArgs(List args) /// /// /// + [Experimental(Experiments.SearchCollect, UrlFormat = Experiments.UrlFormat)] public static CollectReducer Collect() => new CollectReducer(); public static Reducer RandomSample(string field, int size) => new RandomSampleReducer(field, size);