Skip to content

Commit cd33beb

Browse files
Avital-FineNickCraverslorello89
authored
Support ZRANDMEMBER (#2076)
Adds support for https://redis-stack.io/commands/zrandmember/ (#2055) Co-authored-by: Nick Craver <[email protected]> Co-authored-by: Steve Lorello <[email protected]>
1 parent 0e9e698 commit cd33beb

File tree

11 files changed

+290
-3
lines changed

11 files changed

+290
-3
lines changed

docs/ReleaseNotes.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
- Note: does *not* increment a major version (as these are warnings to consumers), because: they're warnings (errors are opt-in), removing obsolete types with a 3.0 rev _would_ be binary breaking (this isn't), and reving to 3.0 would cause binding redirect pain for consumers. Bumping from 2.5 to 2.6 only for this change.
1010
- Adds: Support for `COPY` with `.KeyCopy()`/`.KeyCopyAsync()` ([#2064 by Avital-Fine](https://github.com/StackExchange/StackExchange.Redis/pull/2064))
1111
- Adds: Support for `LMOVE` with `.ListMove()`/`.ListMoveAsync()` ([#2065 by Avital-Fine](https://github.com/StackExchange/StackExchange.Redis/pull/2065))
12+
- Adds: Support for `ZRANDMEMBER` with `.SortedSetRandomMember()`/`.SortedSetRandomMemberAsync()`, `.SortedSetRandomMembers()`/`.SortedSetRandomMembersAsync()`, and `.SortedSetRandomMembersWithScores()`/`.SortedSetRandomMembersWithScoresAsync()` ([#2076 by Avital-Fine](https://github.com/StackExchange/StackExchange.Redis/pull/2076))
1213
- Adds: Support for `SMISMEMBER` with `.SetContains()`/`.SetContainsAsync()` ([#2077 by Avital-Fine](https://github.com/StackExchange/StackExchange.Redis/pull/2077))
1314
- Adds: Support for `SINTERCARD` with `.SetIntersectionLength()`/`.SetIntersectionLengthAsync()` ([#2078 by Avital-Fine](https://github.com/StackExchange/StackExchange.Redis/pull/2078))
1415

src/StackExchange.Redis/Enums/RedisCommand.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ internal enum RedisCommand
201201
ZLEXCOUNT,
202202
ZPOPMAX,
203203
ZPOPMIN,
204+
ZRANDMEMBER,
204205
ZRANGE,
205206
ZRANGEBYLEX,
206207
ZRANGEBYSCORE,

src/StackExchange.Redis/Interfaces/IDatabase.cs

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1199,11 +1199,11 @@ public interface IDatabase : IRedis, IDatabaseAsync
11991199
RedisValue[] SetPop(RedisKey key, long count, CommandFlags flags = CommandFlags.None);
12001200

12011201
/// <summary>
1202-
/// Return a random element from the set value stored at key.
1202+
/// Return a random element from the set value stored at <paramref name="key"/>.
12031203
/// </summary>
12041204
/// <param name="key">The key of the set.</param>
12051205
/// <param name="flags">The flags to use for this operation.</param>
1206-
/// <returns>The randomly selected element, or nil when key does not exist.</returns>
1206+
/// <returns>The randomly selected element, or <see cref="RedisValue.Null"/> when <paramref name="key"/> does not exist.</returns>
12071207
/// <remarks>https://redis.io/commands/srandmember</remarks>
12081208
RedisValue SetRandomMember(RedisKey key, CommandFlags flags = CommandFlags.None);
12091209

@@ -1215,7 +1215,7 @@ public interface IDatabase : IRedis, IDatabaseAsync
12151215
/// <param name="key">The key of the set.</param>
12161216
/// <param name="count">The count of members to get.</param>
12171217
/// <param name="flags">The flags to use for this operation.</param>
1218-
/// <returns>An array of elements, or an empty array when key does not exist.</returns>
1218+
/// <returns>An array of elements, or an empty array when <paramref name="key"/> does not exist.</returns>
12191219
/// <remarks>https://redis.io/commands/srandmember</remarks>
12201220
RedisValue[] SetRandomMembers(RedisKey key, long count, CommandFlags flags = CommandFlags.None);
12211221

@@ -1433,6 +1433,53 @@ public interface IDatabase : IRedis, IDatabaseAsync
14331433
/// <remarks>https://redis.io/commands/zlexcount</remarks>
14341434
long SortedSetLengthByValue(RedisKey key, RedisValue min, RedisValue max, Exclude exclude = Exclude.None, CommandFlags flags = CommandFlags.None);
14351435

1436+
/// <summary>
1437+
/// Returns a random element from the sorted set value stored at <paramref name="key"/>.
1438+
/// </summary>
1439+
/// <param name="key">The key of the sorted set.</param>
1440+
/// <param name="flags">The flags to use for this operation.</param>
1441+
/// <returns>The randomly selected element, or <see cref="RedisValue.Null"/> when <paramref name="key"/> does not exist.</returns>
1442+
/// <remarks>https://redis.io/commands/zrandmember</remarks>
1443+
RedisValue SortedSetRandomMember(RedisKey key, CommandFlags flags = CommandFlags.None);
1444+
1445+
/// <summary>
1446+
/// Returns an array of random elements from the sorted set value stored at <paramref name="key"/>.
1447+
/// </summary>
1448+
/// <param name="key">The key of the sorted set.</param>
1449+
/// <param name="count">
1450+
/// <para>
1451+
/// If the provided count argument is positive, returns an array of distinct elements.
1452+
/// The array's length is either <paramref name="count"/> or the sorted set's cardinality (ZCARD), whichever is lower.
1453+
/// </para>
1454+
/// <para>
1455+
/// If called with a negative count, the behavior changes and the command is allowed to return the same element multiple times.
1456+
/// In this case, the number of returned elements is the absolute value of the specified count.
1457+
/// </para>
1458+
/// </param>
1459+
/// <param name="flags">The flags to use for this operation.</param>
1460+
/// <returns>The randomly selected elements, or an empty array when <paramref name="key"/> does not exist.</returns>
1461+
/// <remarks>https://redis.io/commands/zrandmember</remarks>
1462+
RedisValue[] SortedSetRandomMembers(RedisKey key, long count, CommandFlags flags = CommandFlags.None);
1463+
1464+
/// <summary>
1465+
/// Returns an array of random elements from the sorted set value stored at <paramref name="key"/>.
1466+
/// </summary>
1467+
/// <param name="key">The key of the sorted set.</param>
1468+
/// <param name="count">
1469+
/// <para>
1470+
/// If the provided count argument is positive, returns an array of distinct elements.
1471+
/// The array's length is either <paramref name="count"/> or the sorted set's cardinality (ZCARD), whichever is lower.
1472+
/// </para>
1473+
/// <para>
1474+
/// If called with a negative count, the behavior changes and the command is allowed to return the same element multiple times.
1475+
/// In this case, the number of returned elements is the absolute value of the specified count.
1476+
/// </para>
1477+
/// </param>
1478+
/// <param name="flags">The flags to use for this operation.</param>
1479+
/// <returns>The randomly selected elements with scores, or an empty array when <paramref name="key"/> does not exist.</returns>
1480+
/// <remarks>https://redis.io/commands/zrandmember</remarks>
1481+
SortedSetEntry[] SortedSetRandomMembersWithScores(RedisKey key, long count, CommandFlags flags = CommandFlags.None);
1482+
14361483
/// <summary>
14371484
/// Returns the specified range of elements in the sorted set stored at key.
14381485
/// By default the elements are considered to be ordered from the lowest to the highest score.

src/StackExchange.Redis/Interfaces/IDatabaseAsync.cs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1397,6 +1397,53 @@ public interface IDatabaseAsync : IRedisAsync
13971397
/// <remarks>https://redis.io/commands/zlexcount</remarks>
13981398
Task<long> SortedSetLengthByValueAsync(RedisKey key, RedisValue min, RedisValue max, Exclude exclude = Exclude.None, CommandFlags flags = CommandFlags.None);
13991399

1400+
/// <summary>
1401+
/// Returns a random element from the sorted set value stored at <paramref name="key"/>.
1402+
/// </summary>
1403+
/// <param name="key">The key of the sorted set.</param>
1404+
/// <param name="flags">The flags to use for this operation.</param>
1405+
/// <returns>The randomly selected element, or <see cref="RedisValue.Null"/> when <paramref name="key"/> does not exist.</returns>
1406+
/// <remarks>https://redis.io/commands/zrandmember</remarks>
1407+
Task<RedisValue> SortedSetRandomMemberAsync(RedisKey key, CommandFlags flags = CommandFlags.None);
1408+
1409+
/// <summary>
1410+
/// Returns an array of random elements from the sorted set value stored at <paramref name="key"/>.
1411+
/// </summary>
1412+
/// <param name="key">The key of the sorted set.</param>
1413+
/// <param name="count">
1414+
/// <para>
1415+
/// If the provided count argument is positive, returns an array of distinct elements.
1416+
/// The array's length is either <paramref name="count"/> or the sorted set's cardinality (ZCARD), whichever is lower.
1417+
/// </para>
1418+
/// <para>
1419+
/// If called with a negative count, the behavior changes and the command is allowed to return the same element multiple times.
1420+
/// In this case, the number of returned elements is the absolute value of the specified count.
1421+
/// </para>
1422+
/// </param>
1423+
/// <param name="flags">The flags to use for this operation.</param>
1424+
/// <returns>The randomly selected elements, or an empty array when <paramref name="key"/> does not exist.</returns>
1425+
/// <remarks>https://redis.io/commands/zrandmember</remarks>
1426+
Task<RedisValue[]> SortedSetRandomMembersAsync(RedisKey key, long count, CommandFlags flags = CommandFlags.None);
1427+
1428+
/// <summary>
1429+
/// Returns an array of random elements from the sorted set value stored at <paramref name="key"/>.
1430+
/// </summary>
1431+
/// <param name="key">The key of the sorted set.</param>
1432+
/// <param name="count">
1433+
/// <para>
1434+
/// If the provided count argument is positive, returns an array of distinct elements.
1435+
/// The array's length is either <paramref name="count"/> or the sorted set's cardinality (ZCARD), whichever is lower.
1436+
/// </para>
1437+
/// <para>
1438+
/// If called with a negative count, the behavior changes and the command is allowed to return the same element multiple times.
1439+
/// In this case, the number of returned elements is the absolute value of the specified count.
1440+
/// </para>
1441+
/// </param>
1442+
/// <param name="flags">The flags to use for this operation.</param>
1443+
/// <returns>The randomly selected elements with scores, or an empty array when <paramref name="key"/> does not exist.</returns>
1444+
/// <remarks>https://redis.io/commands/zrandmember</remarks>
1445+
Task<SortedSetEntry[]> SortedSetRandomMembersWithScoresAsync(RedisKey key, long count, CommandFlags flags = CommandFlags.None);
1446+
14001447
/// <summary>
14011448
/// Returns the specified range of elements in the sorted set stored at key.
14021449
/// By default the elements are considered to be ordered from the lowest to the highest score.

src/StackExchange.Redis/KeyspaceIsolation/DatabaseWrapper.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,15 @@ public long SortedSetLength(RedisKey key, double min = -1.0 / 0.0, double max =
363363
public long SortedSetLengthByValue(RedisKey key, RedisValue min, RedisValue max, Exclude exclude = Exclude.None, CommandFlags flags = CommandFlags.None) =>
364364
Inner.SortedSetLengthByValue(ToInner(key), min, max, exclude, flags);
365365

366+
public RedisValue SortedSetRandomMember(RedisKey key, CommandFlags flags = CommandFlags.None) =>
367+
Inner.SortedSetRandomMember(ToInner(key), flags);
368+
369+
public RedisValue[] SortedSetRandomMembers(RedisKey key, long count, CommandFlags flags = CommandFlags.None) =>
370+
Inner.SortedSetRandomMembers(ToInner(key), count, flags);
371+
372+
public SortedSetEntry[] SortedSetRandomMembersWithScores(RedisKey key, long count, CommandFlags flags = CommandFlags.None) =>
373+
Inner.SortedSetRandomMembersWithScores(ToInner(key), count, flags);
374+
366375
public RedisValue[] SortedSetRangeByRank(RedisKey key, long start = 0, long stop = -1, Order order = Order.Ascending, CommandFlags flags = CommandFlags.None) =>
367376
Inner.SortedSetRangeByRank(ToInner(key), start, stop, order, flags);
368377

src/StackExchange.Redis/KeyspaceIsolation/WrapperBase.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,15 @@ public Task<long> SortedSetLengthAsync(RedisKey key, double min = -1.0 / 0.0, do
376376
public Task<long> SortedSetLengthByValueAsync(RedisKey key, RedisValue min, RedisValue max, Exclude exclude = Exclude.None, CommandFlags flags = CommandFlags.None) =>
377377
Inner.SortedSetLengthByValueAsync(ToInner(key), min, max, exclude, flags);
378378

379+
public Task<RedisValue> SortedSetRandomMemberAsync(RedisKey key, CommandFlags flags = CommandFlags.None) =>
380+
Inner.SortedSetRandomMemberAsync(ToInner(key), flags);
381+
382+
public Task<RedisValue[]> SortedSetRandomMembersAsync(RedisKey key, long count, CommandFlags flags = CommandFlags.None) =>
383+
Inner.SortedSetRandomMembersAsync(ToInner(key), count, flags);
384+
385+
public Task<SortedSetEntry[]> SortedSetRandomMembersWithScoresAsync(RedisKey key, long count, CommandFlags flags = CommandFlags.None) =>
386+
Inner.SortedSetRandomMembersWithScoresAsync(ToInner(key), count, flags);
387+
379388
public Task<long> SortedSetRangeAndStoreAsync(
380389
RedisKey sourceKey,
381390
RedisKey destinationKey,

src/StackExchange.Redis/PublicAPI.Shipped.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -600,6 +600,9 @@ StackExchange.Redis.IDatabase.SortedSetLength(StackExchange.Redis.RedisKey key,
600600
StackExchange.Redis.IDatabase.SortedSetLengthByValue(StackExchange.Redis.RedisKey key, StackExchange.Redis.RedisValue min, StackExchange.Redis.RedisValue max, StackExchange.Redis.Exclude exclude = StackExchange.Redis.Exclude.None, StackExchange.Redis.CommandFlags flags = StackExchange.Redis.CommandFlags.None) -> long
601601
StackExchange.Redis.IDatabase.SortedSetPop(StackExchange.Redis.RedisKey key, long count, StackExchange.Redis.Order order = StackExchange.Redis.Order.Ascending, StackExchange.Redis.CommandFlags flags = StackExchange.Redis.CommandFlags.None) -> StackExchange.Redis.SortedSetEntry[]!
602602
StackExchange.Redis.IDatabase.SortedSetPop(StackExchange.Redis.RedisKey key, StackExchange.Redis.Order order = StackExchange.Redis.Order.Ascending, StackExchange.Redis.CommandFlags flags = StackExchange.Redis.CommandFlags.None) -> StackExchange.Redis.SortedSetEntry?
603+
StackExchange.Redis.IDatabase.SortedSetRandomMember(StackExchange.Redis.RedisKey key, StackExchange.Redis.CommandFlags flags = StackExchange.Redis.CommandFlags.None) -> StackExchange.Redis.RedisValue
604+
StackExchange.Redis.IDatabase.SortedSetRandomMembers(StackExchange.Redis.RedisKey key, long count, StackExchange.Redis.CommandFlags flags = StackExchange.Redis.CommandFlags.None) -> StackExchange.Redis.RedisValue[]!
605+
StackExchange.Redis.IDatabase.SortedSetRandomMembersWithScores(StackExchange.Redis.RedisKey key, long count, StackExchange.Redis.CommandFlags flags = StackExchange.Redis.CommandFlags.None) -> StackExchange.Redis.SortedSetEntry[]!
603606
StackExchange.Redis.IDatabase.SortedSetRangeByRank(StackExchange.Redis.RedisKey key, long start = 0, long stop = -1, StackExchange.Redis.Order order = StackExchange.Redis.Order.Ascending, StackExchange.Redis.CommandFlags flags = StackExchange.Redis.CommandFlags.None) -> StackExchange.Redis.RedisValue[]!
604607
StackExchange.Redis.IDatabase.SortedSetRangeAndStore(StackExchange.Redis.RedisKey sourceKey, StackExchange.Redis.RedisKey destinationKey, StackExchange.Redis.RedisValue start, StackExchange.Redis.RedisValue stop, StackExchange.Redis.SortedSetOrder sortedSetOrder = StackExchange.Redis.SortedSetOrder.ByRank, StackExchange.Redis.Exclude exclude = StackExchange.Redis.Exclude.None, StackExchange.Redis.Order order = StackExchange.Redis.Order.Ascending, long skip = 0, long? take = null, StackExchange.Redis.CommandFlags flags = StackExchange.Redis.CommandFlags.None) -> long
605608
StackExchange.Redis.IDatabase.SortedSetRangeByRankWithScores(StackExchange.Redis.RedisKey key, long start = 0, long stop = -1, StackExchange.Redis.Order order = StackExchange.Redis.Order.Ascending, StackExchange.Redis.CommandFlags flags = StackExchange.Redis.CommandFlags.None) -> StackExchange.Redis.SortedSetEntry[]!
@@ -791,6 +794,9 @@ StackExchange.Redis.IDatabaseAsync.SortedSetLengthAsync(StackExchange.Redis.Redi
791794
StackExchange.Redis.IDatabaseAsync.SortedSetLengthByValueAsync(StackExchange.Redis.RedisKey key, StackExchange.Redis.RedisValue min, StackExchange.Redis.RedisValue max, StackExchange.Redis.Exclude exclude = StackExchange.Redis.Exclude.None, StackExchange.Redis.CommandFlags flags = StackExchange.Redis.CommandFlags.None) -> System.Threading.Tasks.Task<long>!
792795
StackExchange.Redis.IDatabaseAsync.SortedSetPopAsync(StackExchange.Redis.RedisKey key, long count, StackExchange.Redis.Order order = StackExchange.Redis.Order.Ascending, StackExchange.Redis.CommandFlags flags = StackExchange.Redis.CommandFlags.None) -> System.Threading.Tasks.Task<StackExchange.Redis.SortedSetEntry[]!>!
793796
StackExchange.Redis.IDatabaseAsync.SortedSetPopAsync(StackExchange.Redis.RedisKey key, StackExchange.Redis.Order order = StackExchange.Redis.Order.Ascending, StackExchange.Redis.CommandFlags flags = StackExchange.Redis.CommandFlags.None) -> System.Threading.Tasks.Task<StackExchange.Redis.SortedSetEntry?>!
797+
StackExchange.Redis.IDatabaseAsync.SortedSetRandomMemberAsync(StackExchange.Redis.RedisKey key, StackExchange.Redis.CommandFlags flags = StackExchange.Redis.CommandFlags.None) -> System.Threading.Tasks.Task<StackExchange.Redis.RedisValue>!
798+
StackExchange.Redis.IDatabaseAsync.SortedSetRandomMembersAsync(StackExchange.Redis.RedisKey key, long count, StackExchange.Redis.CommandFlags flags = StackExchange.Redis.CommandFlags.None) -> System.Threading.Tasks.Task<StackExchange.Redis.RedisValue[]!>!
799+
StackExchange.Redis.IDatabaseAsync.SortedSetRandomMembersWithScoresAsync(StackExchange.Redis.RedisKey key, long count, StackExchange.Redis.CommandFlags flags = StackExchange.Redis.CommandFlags.None) -> System.Threading.Tasks.Task<StackExchange.Redis.SortedSetEntry[]!>!
794800
StackExchange.Redis.IDatabaseAsync.SortedSetRangeAndStoreAsync(StackExchange.Redis.RedisKey sourceKey, StackExchange.Redis.RedisKey destinationKey, StackExchange.Redis.RedisValue start, StackExchange.Redis.RedisValue stop, StackExchange.Redis.SortedSetOrder sortedSetOrder = StackExchange.Redis.SortedSetOrder.ByRank, StackExchange.Redis.Exclude exclude = StackExchange.Redis.Exclude.None, StackExchange.Redis.Order order = StackExchange.Redis.Order.Ascending, long skip = 0, long? take = null, StackExchange.Redis.CommandFlags flags = StackExchange.Redis.CommandFlags.None) -> System.Threading.Tasks.Task<long>!
795801
StackExchange.Redis.IDatabaseAsync.SortedSetRangeByRankAsync(StackExchange.Redis.RedisKey key, long start = 0, long stop = -1, StackExchange.Redis.Order order = StackExchange.Redis.Order.Ascending, StackExchange.Redis.CommandFlags flags = StackExchange.Redis.CommandFlags.None) -> System.Threading.Tasks.Task<StackExchange.Redis.RedisValue[]!>!
796802
StackExchange.Redis.IDatabaseAsync.SortedSetRangeByRankWithScoresAsync(StackExchange.Redis.RedisKey key, long start = 0, long stop = -1, StackExchange.Redis.Order order = StackExchange.Redis.Order.Ascending, StackExchange.Redis.CommandFlags flags = StackExchange.Redis.CommandFlags.None) -> System.Threading.Tasks.Task<StackExchange.Redis.SortedSetEntry[]!>!

0 commit comments

Comments
 (0)