diff --git a/docs/ReleaseNotes.md b/docs/ReleaseNotes.md
index b3bc9845e..38d9abf19 100644
--- a/docs/ReleaseNotes.md
+++ b/docs/ReleaseNotes.md
@@ -9,6 +9,7 @@
- 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.
- Adds: Support for `COPY` with `.KeyCopy()`/`.KeyCopyAsync()` ([#2064 by Avital-Fine](https://github.com/StackExchange/StackExchange.Redis/pull/2064))
- Adds: Support for `LMOVE` with `.ListMove()`/`.ListMoveAsync()` ([#2065 by Avital-Fine](https://github.com/StackExchange/StackExchange.Redis/pull/2065))
+- Adds: Support for `ZRANDMEMBER` with `.SortedSetRandomMember()`/`.SortedSetRandomMemberAsync()`, `.SortedSetRandomMembers()`/`.SortedSetRandomMembersAsync()`, and `.SortedSetRandomMembersWithScores()`/`.SortedSetRandomMembersWithScoresAsync()` ([#2076 by Avital-Fine](https://github.com/StackExchange/StackExchange.Redis/pull/2076))
- Adds: Support for `SMISMEMBER` with `.SetContains()`/`.SetContainsAsync()` ([#2077 by Avital-Fine](https://github.com/StackExchange/StackExchange.Redis/pull/2077))
- Adds: Support for `SINTERCARD` with `.SetIntersectionLength()`/`.SetIntersectionLengthAsync()` ([#2078 by Avital-Fine](https://github.com/StackExchange/StackExchange.Redis/pull/2078))
diff --git a/src/StackExchange.Redis/Enums/RedisCommand.cs b/src/StackExchange.Redis/Enums/RedisCommand.cs
index b4d3c5fd7..f0020cda4 100644
--- a/src/StackExchange.Redis/Enums/RedisCommand.cs
+++ b/src/StackExchange.Redis/Enums/RedisCommand.cs
@@ -201,6 +201,7 @@ internal enum RedisCommand
ZLEXCOUNT,
ZPOPMAX,
ZPOPMIN,
+ ZRANDMEMBER,
ZRANGE,
ZRANGEBYLEX,
ZRANGEBYSCORE,
diff --git a/src/StackExchange.Redis/Interfaces/IDatabase.cs b/src/StackExchange.Redis/Interfaces/IDatabase.cs
index c6887608f..3eef153e4 100644
--- a/src/StackExchange.Redis/Interfaces/IDatabase.cs
+++ b/src/StackExchange.Redis/Interfaces/IDatabase.cs
@@ -1199,11 +1199,11 @@ public interface IDatabase : IRedis, IDatabaseAsync
RedisValue[] SetPop(RedisKey key, long count, CommandFlags flags = CommandFlags.None);
///
- /// Return a random element from the set value stored at key.
+ /// Return a random element from the set value stored at .
///
/// The key of the set.
/// The flags to use for this operation.
- /// The randomly selected element, or nil when key does not exist.
+ /// The randomly selected element, or when does not exist.
/// https://redis.io/commands/srandmember
RedisValue SetRandomMember(RedisKey key, CommandFlags flags = CommandFlags.None);
@@ -1215,7 +1215,7 @@ public interface IDatabase : IRedis, IDatabaseAsync
/// The key of the set.
/// The count of members to get.
/// The flags to use for this operation.
- /// An array of elements, or an empty array when key does not exist.
+ /// An array of elements, or an empty array when does not exist.
/// https://redis.io/commands/srandmember
RedisValue[] SetRandomMembers(RedisKey key, long count, CommandFlags flags = CommandFlags.None);
@@ -1433,6 +1433,53 @@ public interface IDatabase : IRedis, IDatabaseAsync
/// https://redis.io/commands/zlexcount
long SortedSetLengthByValue(RedisKey key, RedisValue min, RedisValue max, Exclude exclude = Exclude.None, CommandFlags flags = CommandFlags.None);
+ ///
+ /// Returns a random element from the sorted set value stored at .
+ ///
+ /// The key of the sorted set.
+ /// The flags to use for this operation.
+ /// The randomly selected element, or when does not exist.
+ /// https://redis.io/commands/zrandmember
+ RedisValue SortedSetRandomMember(RedisKey key, CommandFlags flags = CommandFlags.None);
+
+ ///
+ /// Returns an array of random elements from the sorted set value stored at .
+ ///
+ /// The key of the sorted set.
+ ///
+ ///
+ /// If the provided count argument is positive, returns an array of distinct elements.
+ /// The array's length is either or the sorted set's cardinality (ZCARD), whichever is lower.
+ ///
+ ///
+ /// If called with a negative count, the behavior changes and the command is allowed to return the same element multiple times.
+ /// In this case, the number of returned elements is the absolute value of the specified count.
+ ///
+ ///
+ /// The flags to use for this operation.
+ /// The randomly selected elements, or an empty array when does not exist.
+ /// https://redis.io/commands/zrandmember
+ RedisValue[] SortedSetRandomMembers(RedisKey key, long count, CommandFlags flags = CommandFlags.None);
+
+ ///
+ /// Returns an array of random elements from the sorted set value stored at .
+ ///
+ /// The key of the sorted set.
+ ///
+ ///
+ /// If the provided count argument is positive, returns an array of distinct elements.
+ /// The array's length is either or the sorted set's cardinality (ZCARD), whichever is lower.
+ ///
+ ///
+ /// If called with a negative count, the behavior changes and the command is allowed to return the same element multiple times.
+ /// In this case, the number of returned elements is the absolute value of the specified count.
+ ///
+ ///
+ /// The flags to use for this operation.
+ /// The randomly selected elements with scores, or an empty array when does not exist.
+ /// https://redis.io/commands/zrandmember
+ SortedSetEntry[] SortedSetRandomMembersWithScores(RedisKey key, long count, CommandFlags flags = CommandFlags.None);
+
///
/// Returns the specified range of elements in the sorted set stored at key.
/// By default the elements are considered to be ordered from the lowest to the highest score.
diff --git a/src/StackExchange.Redis/Interfaces/IDatabaseAsync.cs b/src/StackExchange.Redis/Interfaces/IDatabaseAsync.cs
index 45074dd6d..1ec8d7e30 100644
--- a/src/StackExchange.Redis/Interfaces/IDatabaseAsync.cs
+++ b/src/StackExchange.Redis/Interfaces/IDatabaseAsync.cs
@@ -1397,6 +1397,53 @@ public interface IDatabaseAsync : IRedisAsync
/// https://redis.io/commands/zlexcount
Task SortedSetLengthByValueAsync(RedisKey key, RedisValue min, RedisValue max, Exclude exclude = Exclude.None, CommandFlags flags = CommandFlags.None);
+ ///
+ /// Returns a random element from the sorted set value stored at .
+ ///
+ /// The key of the sorted set.
+ /// The flags to use for this operation.
+ /// The randomly selected element, or when does not exist.
+ /// https://redis.io/commands/zrandmember
+ Task SortedSetRandomMemberAsync(RedisKey key, CommandFlags flags = CommandFlags.None);
+
+ ///
+ /// Returns an array of random elements from the sorted set value stored at .
+ ///
+ /// The key of the sorted set.
+ ///
+ ///
+ /// If the provided count argument is positive, returns an array of distinct elements.
+ /// The array's length is either or the sorted set's cardinality (ZCARD), whichever is lower.
+ ///
+ ///
+ /// If called with a negative count, the behavior changes and the command is allowed to return the same element multiple times.
+ /// In this case, the number of returned elements is the absolute value of the specified count.
+ ///
+ ///
+ /// The flags to use for this operation.
+ /// The randomly selected elements, or an empty array when does not exist.
+ /// https://redis.io/commands/zrandmember
+ Task SortedSetRandomMembersAsync(RedisKey key, long count, CommandFlags flags = CommandFlags.None);
+
+ ///
+ /// Returns an array of random elements from the sorted set value stored at .
+ ///
+ /// The key of the sorted set.
+ ///
+ ///
+ /// If the provided count argument is positive, returns an array of distinct elements.
+ /// The array's length is either or the sorted set's cardinality (ZCARD), whichever is lower.
+ ///
+ ///
+ /// If called with a negative count, the behavior changes and the command is allowed to return the same element multiple times.
+ /// In this case, the number of returned elements is the absolute value of the specified count.
+ ///
+ ///
+ /// The flags to use for this operation.
+ /// The randomly selected elements with scores, or an empty array when does not exist.
+ /// https://redis.io/commands/zrandmember
+ Task SortedSetRandomMembersWithScoresAsync(RedisKey key, long count, CommandFlags flags = CommandFlags.None);
+
///
/// Returns the specified range of elements in the sorted set stored at key.
/// By default the elements are considered to be ordered from the lowest to the highest score.
diff --git a/src/StackExchange.Redis/KeyspaceIsolation/DatabaseWrapper.cs b/src/StackExchange.Redis/KeyspaceIsolation/DatabaseWrapper.cs
index 9563d4d13..c56209de1 100644
--- a/src/StackExchange.Redis/KeyspaceIsolation/DatabaseWrapper.cs
+++ b/src/StackExchange.Redis/KeyspaceIsolation/DatabaseWrapper.cs
@@ -363,6 +363,15 @@ public long SortedSetLength(RedisKey key, double min = -1.0 / 0.0, double max =
public long SortedSetLengthByValue(RedisKey key, RedisValue min, RedisValue max, Exclude exclude = Exclude.None, CommandFlags flags = CommandFlags.None) =>
Inner.SortedSetLengthByValue(ToInner(key), min, max, exclude, flags);
+ public RedisValue SortedSetRandomMember(RedisKey key, CommandFlags flags = CommandFlags.None) =>
+ Inner.SortedSetRandomMember(ToInner(key), flags);
+
+ public RedisValue[] SortedSetRandomMembers(RedisKey key, long count, CommandFlags flags = CommandFlags.None) =>
+ Inner.SortedSetRandomMembers(ToInner(key), count, flags);
+
+ public SortedSetEntry[] SortedSetRandomMembersWithScores(RedisKey key, long count, CommandFlags flags = CommandFlags.None) =>
+ Inner.SortedSetRandomMembersWithScores(ToInner(key), count, flags);
+
public RedisValue[] SortedSetRangeByRank(RedisKey key, long start = 0, long stop = -1, Order order = Order.Ascending, CommandFlags flags = CommandFlags.None) =>
Inner.SortedSetRangeByRank(ToInner(key), start, stop, order, flags);
diff --git a/src/StackExchange.Redis/KeyspaceIsolation/WrapperBase.cs b/src/StackExchange.Redis/KeyspaceIsolation/WrapperBase.cs
index 87f40b608..969637abd 100644
--- a/src/StackExchange.Redis/KeyspaceIsolation/WrapperBase.cs
+++ b/src/StackExchange.Redis/KeyspaceIsolation/WrapperBase.cs
@@ -376,6 +376,15 @@ public Task SortedSetLengthAsync(RedisKey key, double min = -1.0 / 0.0, do
public Task SortedSetLengthByValueAsync(RedisKey key, RedisValue min, RedisValue max, Exclude exclude = Exclude.None, CommandFlags flags = CommandFlags.None) =>
Inner.SortedSetLengthByValueAsync(ToInner(key), min, max, exclude, flags);
+ public Task SortedSetRandomMemberAsync(RedisKey key, CommandFlags flags = CommandFlags.None) =>
+ Inner.SortedSetRandomMemberAsync(ToInner(key), flags);
+
+ public Task SortedSetRandomMembersAsync(RedisKey key, long count, CommandFlags flags = CommandFlags.None) =>
+ Inner.SortedSetRandomMembersAsync(ToInner(key), count, flags);
+
+ public Task SortedSetRandomMembersWithScoresAsync(RedisKey key, long count, CommandFlags flags = CommandFlags.None) =>
+ Inner.SortedSetRandomMembersWithScoresAsync(ToInner(key), count, flags);
+
public Task SortedSetRangeAndStoreAsync(
RedisKey sourceKey,
RedisKey destinationKey,
diff --git a/src/StackExchange.Redis/PublicAPI.Shipped.txt b/src/StackExchange.Redis/PublicAPI.Shipped.txt
index 4f07e98e2..b31fa1a9e 100644
--- a/src/StackExchange.Redis/PublicAPI.Shipped.txt
+++ b/src/StackExchange.Redis/PublicAPI.Shipped.txt
@@ -600,6 +600,9 @@ StackExchange.Redis.IDatabase.SortedSetLength(StackExchange.Redis.RedisKey key,
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
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[]!
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?
+StackExchange.Redis.IDatabase.SortedSetRandomMember(StackExchange.Redis.RedisKey key, StackExchange.Redis.CommandFlags flags = StackExchange.Redis.CommandFlags.None) -> StackExchange.Redis.RedisValue
+StackExchange.Redis.IDatabase.SortedSetRandomMembers(StackExchange.Redis.RedisKey key, long count, StackExchange.Redis.CommandFlags flags = StackExchange.Redis.CommandFlags.None) -> StackExchange.Redis.RedisValue[]!
+StackExchange.Redis.IDatabase.SortedSetRandomMembersWithScores(StackExchange.Redis.RedisKey key, long count, StackExchange.Redis.CommandFlags flags = StackExchange.Redis.CommandFlags.None) -> StackExchange.Redis.SortedSetEntry[]!
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[]!
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
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
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!
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.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.IDatabaseAsync.SortedSetRandomMemberAsync(StackExchange.Redis.RedisKey key, StackExchange.Redis.CommandFlags flags = StackExchange.Redis.CommandFlags.None) -> System.Threading.Tasks.Task!
+StackExchange.Redis.IDatabaseAsync.SortedSetRandomMembersAsync(StackExchange.Redis.RedisKey key, long count, StackExchange.Redis.CommandFlags flags = StackExchange.Redis.CommandFlags.None) -> System.Threading.Tasks.Task!
+StackExchange.Redis.IDatabaseAsync.SortedSetRandomMembersWithScoresAsync(StackExchange.Redis.RedisKey key, long count, StackExchange.Redis.CommandFlags flags = StackExchange.Redis.CommandFlags.None) -> System.Threading.Tasks.Task!
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!
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.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!
diff --git a/src/StackExchange.Redis/RedisDatabase.cs b/src/StackExchange.Redis/RedisDatabase.cs
index 54181f982..aaa647e19 100644
--- a/src/StackExchange.Redis/RedisDatabase.cs
+++ b/src/StackExchange.Redis/RedisDatabase.cs
@@ -1674,6 +1674,42 @@ public Task SortedSetLengthAsync(RedisKey key, double min = double.Negativ
return ExecuteAsync(msg, ResultProcessor.Int64);
}
+ public RedisValue SortedSetRandomMember(RedisKey key, CommandFlags flags = CommandFlags.None)
+ {
+ var msg = Message.Create(Database, flags, RedisCommand.ZRANDMEMBER, key);
+ return ExecuteSync(msg, ResultProcessor.RedisValue);
+ }
+
+ public RedisValue[] SortedSetRandomMembers(RedisKey key, long count, CommandFlags flags = CommandFlags.None)
+ {
+ var msg = Message.Create(Database, flags, RedisCommand.ZRANDMEMBER, key, count);
+ return ExecuteSync(msg, ResultProcessor.RedisValueArray, defaultValue: Array.Empty());
+ }
+
+ public SortedSetEntry[] SortedSetRandomMembersWithScores(RedisKey key, long count, CommandFlags flags = CommandFlags.None)
+ {
+ var msg = Message.Create(Database, flags, RedisCommand.ZRANDMEMBER, key, count, RedisLiterals.WITHSCORES);
+ return ExecuteSync(msg, ResultProcessor.SortedSetWithScores, defaultValue: Array.Empty());
+ }
+
+ public Task SortedSetRandomMemberAsync(RedisKey key, CommandFlags flags = CommandFlags.None)
+ {
+ var msg = Message.Create(Database, flags, RedisCommand.ZRANDMEMBER, key);
+ return ExecuteAsync(msg, ResultProcessor.RedisValue);
+ }
+
+ public Task SortedSetRandomMembersAsync(RedisKey key, long count, CommandFlags flags = CommandFlags.None)
+ {
+ var msg = Message.Create(Database, flags, RedisCommand.ZRANDMEMBER, key, count);
+ return ExecuteAsync(msg, ResultProcessor.RedisValueArray, defaultValue: Array.Empty());
+ }
+
+ public Task SortedSetRandomMembersWithScoresAsync(RedisKey key, long count, CommandFlags flags = CommandFlags.None)
+ {
+ var msg = Message.Create(Database, flags, RedisCommand.ZRANDMEMBER, key, count, RedisLiterals.WITHSCORES);
+ return ExecuteAsync(msg, ResultProcessor.SortedSetWithScores, defaultValue: Array.Empty());
+ }
+
public RedisValue[] SortedSetRangeByRank(RedisKey key, long start = 0, long stop = -1, Order order = Order.Ascending, CommandFlags flags = CommandFlags.None)
{
var msg = Message.Create(Database, flags, order == Order.Descending ? RedisCommand.ZREVRANGE : RedisCommand.ZRANGE, key, start, stop);
diff --git a/tests/StackExchange.Redis.Tests/DatabaseWrapperTests.cs b/tests/StackExchange.Redis.Tests/DatabaseWrapperTests.cs
index 78db3c07a..5b2018858 100644
--- a/tests/StackExchange.Redis.Tests/DatabaseWrapperTests.cs
+++ b/tests/StackExchange.Redis.Tests/DatabaseWrapperTests.cs
@@ -778,6 +778,27 @@ public void SortedSetLength()
mock.Verify(_ => _.SortedSetLength("prefix:key", 1.23, 1.23, Exclude.Start, CommandFlags.None));
}
+ [Fact]
+ public void SortedSetRandomMember()
+ {
+ wrapper.SortedSetRandomMember("key", CommandFlags.None);
+ mock.Verify(_ => _.SortedSetRandomMember("prefix:key", CommandFlags.None));
+ }
+
+ [Fact]
+ public void SortedSetRandomMembers()
+ {
+ wrapper.SortedSetRandomMembers("key", 2, CommandFlags.None);
+ mock.Verify(_ => _.SortedSetRandomMembers("prefix:key", 2, CommandFlags.None));
+ }
+
+ [Fact]
+ public void SortedSetRandomMembersWithScores()
+ {
+ wrapper.SortedSetRandomMembersWithScores("key", 2, CommandFlags.None);
+ mock.Verify(_ => _.SortedSetRandomMembersWithScores("prefix:key", 2, CommandFlags.None));
+ }
+
[Fact]
public void SortedSetLengthByValue()
{
diff --git a/tests/StackExchange.Redis.Tests/SortedSets.cs b/tests/StackExchange.Redis.Tests/SortedSets.cs
index e7cdcc59c..f15779d78 100644
--- a/tests/StackExchange.Redis.Tests/SortedSets.cs
+++ b/tests/StackExchange.Redis.Tests/SortedSets.cs
@@ -177,6 +177,95 @@ public async Task SortedSetPopMulti_Zero_Async()
}
}
+ [Fact]
+ public void SortedSetRandomMembers()
+ {
+ using var conn = Create();
+ Skip.IfBelow(conn, RedisFeatures.v6_2_0);
+
+ var db = conn.GetDatabase();
+ var key = Me();
+ var key0 = Me() + "non-existing";
+
+ db.KeyDelete(key, CommandFlags.FireAndForget);
+ db.KeyDelete(key0, CommandFlags.FireAndForget);
+ db.SortedSetAdd(key, entries, CommandFlags.FireAndForget);
+
+ // single member
+ var randMember = db.SortedSetRandomMember(key);
+ Assert.True(Array.Exists(entries, element => element.Element.Equals(randMember)));
+
+ // with count
+ var randMemberArray = db.SortedSetRandomMembers(key, 5);
+ Assert.Equal(5, randMemberArray.Length);
+ randMemberArray = db.SortedSetRandomMembers(key, 15);
+ Assert.Equal(10, randMemberArray.Length);
+ randMemberArray = db.SortedSetRandomMembers(key, -5);
+ Assert.Equal(5, randMemberArray.Length);
+ randMemberArray = db.SortedSetRandomMembers(key, -15);
+ Assert.Equal(15, randMemberArray.Length);
+
+ // with scores
+ var randMemberArray2 = db.SortedSetRandomMembersWithScores(key, 2);
+ Assert.Equal(2, randMemberArray2.Length);
+ foreach (var member in randMemberArray2)
+ {
+ Assert.Contains(member, entries);
+ }
+
+ // check missing key case
+ randMember = db.SortedSetRandomMember(key0);
+ Assert.True(randMember.IsNull);
+ randMemberArray = db.SortedSetRandomMembers(key0, 2);
+ Assert.True(randMemberArray.Length == 0);
+ randMemberArray2 = db.SortedSetRandomMembersWithScores(key0, 2);
+ Assert.True(randMemberArray2.Length == 0);
+ }
+
+ [Fact]
+ public async Task SortedSetRandomMembersAsync()
+ {
+ using var conn = Create();
+ Skip.IfBelow(conn, RedisFeatures.v6_2_0);
+
+ var db = conn.GetDatabase();
+ var key = Me();
+ var key0 = Me() + "non-existing";
+
+ db.KeyDelete(key, CommandFlags.FireAndForget);
+ db.KeyDelete(key0, CommandFlags.FireAndForget);
+ db.SortedSetAdd(key, entries, CommandFlags.FireAndForget);
+
+ var randMember = await db.SortedSetRandomMemberAsync(key);
+ Assert.True(Array.Exists(entries, element => element.Element.Equals(randMember)));
+
+ // with count
+ var randMemberArray = await db.SortedSetRandomMembersAsync(key, 5);
+ Assert.Equal(5, randMemberArray.Length);
+ randMemberArray = await db.SortedSetRandomMembersAsync(key, 15);
+ Assert.Equal(10, randMemberArray.Length);
+ randMemberArray = await db.SortedSetRandomMembersAsync(key, -5);
+ Assert.Equal(5, randMemberArray.Length);
+ randMemberArray = await db.SortedSetRandomMembersAsync(key, -15);
+ Assert.Equal(15, randMemberArray.Length);
+
+ // with scores
+ var randMemberArray2 = await db.SortedSetRandomMembersWithScoresAsync(key, 2);
+ Assert.Equal(2, randMemberArray2.Length);
+ foreach (var member in randMemberArray2)
+ {
+ Assert.Contains(member, entries);
+ }
+
+ // check missing key case
+ randMember = await db.SortedSetRandomMemberAsync(key0);
+ Assert.True(randMember.IsNull);
+ randMemberArray = await db.SortedSetRandomMembersAsync(key0, 2);
+ Assert.True(randMemberArray.Length == 0);
+ randMemberArray2 = await db.SortedSetRandomMembersWithScoresAsync(key0, 2);
+ Assert.True(randMemberArray2.Length == 0);
+ }
+
[Fact]
public async Task SortedSetRangeStoreByRankAsync()
{
diff --git a/tests/StackExchange.Redis.Tests/WrapperBaseTests.cs b/tests/StackExchange.Redis.Tests/WrapperBaseTests.cs
index 322f71a3f..1f293266d 100644
--- a/tests/StackExchange.Redis.Tests/WrapperBaseTests.cs
+++ b/tests/StackExchange.Redis.Tests/WrapperBaseTests.cs
@@ -731,6 +731,27 @@ public void SortedSetLengthByValueAsync()
mock.Verify(_ => _.SortedSetLengthByValueAsync("prefix:key", "min", "max", Exclude.Start, CommandFlags.None));
}
+ [Fact]
+ public void SortedSetRandomMemberAsync()
+ {
+ wrapper.SortedSetRandomMemberAsync("key", CommandFlags.None);
+ mock.Verify(_ => _.SortedSetRandomMemberAsync("prefix:key", CommandFlags.None));
+ }
+
+ [Fact]
+ public void SortedSetRandomMembersAsync()
+ {
+ wrapper.SortedSetRandomMembersAsync("key", 2, CommandFlags.None);
+ mock.Verify(_ => _.SortedSetRandomMembersAsync("prefix:key", 2, CommandFlags.None));
+ }
+
+ [Fact]
+ public void SortedSetRandomMemberWithScoresAsync()
+ {
+ wrapper.SortedSetRandomMembersWithScoresAsync("key", 2, CommandFlags.None);
+ mock.Verify(_ => _.SortedSetRandomMembersWithScoresAsync("prefix:key", 2, CommandFlags.None));
+ }
+
[Fact]
public void SortedSetRangeByRankAsync()
{