Skip to content

Commit 4ef2f42

Browse files
committed
Add support for ZMSCORE through score(key, values).
We now support Redis 6.2 ZMSCORE through the Template API and on the connection level for all drivers. Closes #2038
1 parent 12f91e9 commit 4ef2f42

29 files changed

+399
-7
lines changed

src/main/asciidoc/new-features.adoc

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ This section briefly covers items that are new and noteworthy in the latest rele
77
== New in Spring Data Redis 2.6
88

99
* Support for `SubscriptionListener` when using `MessageListener` for subscription confirmation callbacks. `ReactiveRedisMessageListenerContainer` and `ReactiveRedisOperations` provide `receiveLater(…)` and `listenToLater(…)` methods to await until Redis acknowledges the subscription.
10-
* Support Redis 6.2 commands (`LPOP`/`RPOP` with `count`, `COPY`).
10+
* Support Redis 6.2 commands (`LPOP`/`RPOP` with `count`, `COPY`, `ZMSCORE`).
1111

1212
[[new-in-2.5.0]]
1313
== New in Spring Data Redis 2.5

src/main/java/org/springframework/data/redis/connection/DefaultStringRedisConnection.java

+18
Original file line numberDiff line numberDiff line change
@@ -1682,6 +1682,15 @@ public Double zScore(byte[] key, byte[] value) {
16821682
return convertAndReturn(delegate.zScore(key, value), Converters.identityConverter());
16831683
}
16841684

1685+
/*
1686+
* (non-Javadoc)
1687+
* @see org.springframework.data.redis.connection.RedisZSetCommands#zMScore(byte[], byte[][])
1688+
*/
1689+
@Override
1690+
public List<Double> zMScore(byte[] key, byte[]... values) {
1691+
return convertAndReturn(delegate.zMScore(key, values), Converters.identityConverter());
1692+
}
1693+
16851694
/*
16861695
* (non-Javadoc)
16871696
* @see org.springframework.data.redis.connection.RedisZSetCommands#zUnionStore(byte[], org.springframework.data.redis.connection.RedisZSetCommands.Aggregate, org.springframework.data.redis.connection.RedisZSetCommands.Weights, byte[][])
@@ -3012,6 +3021,15 @@ public Double zScore(String key, String value) {
30123021
return zScore(serialize(key), serialize(value));
30133022
}
30143023

3024+
/*
3025+
* (non-Javadoc)
3026+
* @see org.springframework.data.redis.connection.StringRedisConnection#zMScore(java.lang.String, java.lang.String[])
3027+
*/
3028+
@Override
3029+
public List<Double> zMScore(String key, String... values) {
3030+
return zMScore(serialize(key), serializeMulti(values));
3031+
}
3032+
30153033
/*
30163034
* (non-Javadoc)
30173035
* @see org.springframework.data.redis.connection.StringRedisConnection#zUnionStore(java.lang.String, org.springframework.data.redis.connection.RedisZSetCommands.Aggregate, int[], java.lang.String[])

src/main/java/org/springframework/data/redis/connection/DefaultedRedisConnection.java

+7
Original file line numberDiff line numberDiff line change
@@ -1089,6 +1089,13 @@ default Double zScore(byte[] key, byte[] value) {
10891089
return zSetCommands().zScore(key, value);
10901090
}
10911091

1092+
/** @deprecated in favor of {@link RedisConnection#zSetCommands()}}. */
1093+
@Override
1094+
@Deprecated
1095+
default List<Double> zMScore(byte[] key, byte[]... values) {
1096+
return zSetCommands().zMScore(key, values);
1097+
}
1098+
10921099
/** @deprecated in favor of {@link RedisConnection#zSetCommands()}}. */
10931100
@Override
10941101
@Deprecated

src/main/java/org/springframework/data/redis/connection/ReactiveZSetCommands.java

+98-4
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import org.springframework.data.redis.connection.ReactiveRedisConnection.CommandResponse;
3232
import org.springframework.data.redis.connection.ReactiveRedisConnection.KeyCommand;
3333
import org.springframework.data.redis.connection.ReactiveRedisConnection.KeyScanCommand;
34+
import org.springframework.data.redis.connection.ReactiveRedisConnection.MultiValueResponse;
3435
import org.springframework.data.redis.connection.ReactiveRedisConnection.NumericResponse;
3536
import org.springframework.data.redis.connection.RedisZSetCommands.Aggregate;
3637
import org.springframework.data.redis.connection.RedisZSetCommands.Limit;
@@ -292,7 +293,7 @@ private ZRemCommand(@Nullable ByteBuffer key, List<ByteBuffer> values) {
292293
* Creates a new {@link ZRemCommand} given a {@link Tuple}.
293294
*
294295
* @param value must not be {@literal null}.
295-
* @return a new {@link ZAddCommand} for {@link Tuple}.
296+
* @return a new {@link ZRemCommand} for {@link Tuple}.
296297
*/
297298
public static ZRemCommand values(ByteBuffer value) {
298299

@@ -305,7 +306,7 @@ public static ZRemCommand values(ByteBuffer value) {
305306
* Creates a new {@link ZRemCommand} given a {@link Collection} of {@link Tuple}.
306307
*
307308
* @param values must not be {@literal null}.
308-
* @return a new {@link ZAddCommand} for {@link Tuple}.
309+
* @return a new {@link ZRemCommand} for {@link Tuple}.
309310
*/
310311
public static ZRemCommand values(Collection<ByteBuffer> values) {
311312

@@ -1283,7 +1284,7 @@ private ZScoreCommand(@Nullable ByteBuffer key, ByteBuffer value) {
12831284
* Creates a new {@link ZScoreCommand} given a {@link ByteBuffer member}.
12841285
*
12851286
* @param member must not be {@literal null}.
1286-
* @return a new {@link ZScoreCommand} for {@link Range}.
1287+
* @return a new {@link ZScoreCommand} for {@link ByteBuffer member}.
12871288
*/
12881289
public static ZScoreCommand scoreOf(ByteBuffer member) {
12891290

@@ -1339,6 +1340,99 @@ default Mono<Double> zScore(ByteBuffer key, ByteBuffer value) {
13391340
*/
13401341
Flux<NumericResponse<ZScoreCommand, Double>> zScore(Publisher<ZScoreCommand> commands);
13411342

1343+
/**
1344+
* {@code ZMSCORE} command parameters.
1345+
*
1346+
* @author Mark Paluch
1347+
* @see <a href="https://redis.io/commands/zmscore">Redis Documentation: ZMSCORE</a>
1348+
* @since 2.6
1349+
*/
1350+
class ZMScoreCommand extends KeyCommand {
1351+
1352+
private final Collection<ByteBuffer> values;
1353+
1354+
private ZMScoreCommand(@Nullable ByteBuffer key, Collection<ByteBuffer> values) {
1355+
1356+
super(key);
1357+
1358+
this.values = values;
1359+
}
1360+
1361+
/**
1362+
* Creates a new {@link ZMScoreCommand} given a {@link ByteBuffer member}.
1363+
*
1364+
* @param member must not be {@literal null}.
1365+
* @return a new {@link ZMScoreCommand} for {@link ByteBuffer}.
1366+
*/
1367+
public static ZMScoreCommand scoreOf(ByteBuffer member) {
1368+
1369+
Assert.notNull(member, "Member must not be null!");
1370+
1371+
return new ZMScoreCommand(null, Collections.singletonList(member));
1372+
}
1373+
1374+
/**
1375+
* Creates a new {@link ZMScoreCommand} given a {@link List members}.
1376+
*
1377+
* @param member must not be {@literal null}.
1378+
* @return a new {@link ZMScoreCommand} for {@link List} of members.
1379+
*/
1380+
public static ZMScoreCommand scoreOf(Collection<ByteBuffer> members) {
1381+
1382+
Assert.notNull(members, "Members must not be null!");
1383+
1384+
return new ZMScoreCommand(null, members);
1385+
}
1386+
1387+
/**
1388+
* Applies the {@literal key}. Constructs a new command instance with all previously configured properties.
1389+
*
1390+
* @param key must not be {@literal null}.
1391+
* @return a new {@link ZMScoreCommand} with {@literal key} applied.
1392+
*/
1393+
public ZMScoreCommand forKey(ByteBuffer key) {
1394+
1395+
Assert.notNull(key, "Key must not be null!");
1396+
1397+
return new ZMScoreCommand(key, values);
1398+
}
1399+
1400+
/**
1401+
* @return
1402+
*/
1403+
public Collection<ByteBuffer> getValues() {
1404+
return values;
1405+
}
1406+
}
1407+
1408+
/**
1409+
* Get the scores of elements with {@literal values} from sorted set with key {@literal key}.
1410+
*
1411+
* @param key must not be {@literal null}.
1412+
* @param values must not be {@literal null}.
1413+
* @return
1414+
* @see <a href="https://redis.io/commands/zmscore">Redis Documentation: ZMSCORE</a>
1415+
* @since 2.6
1416+
*/
1417+
default Mono<List<Double>> zMScore(ByteBuffer key, Collection<ByteBuffer> values) {
1418+
1419+
Assert.notNull(key, "Key must not be null!");
1420+
Assert.notNull(values, "Values must not be null!");
1421+
1422+
return zMScore(Mono.just(ZMScoreCommand.scoreOf(values).forKey(key))).next().map(MultiValueResponse::getOutput);
1423+
}
1424+
1425+
/**
1426+
* Get the scores of elements with {@link ZMScoreCommand#getValues()} from sorted set with key
1427+
* {@link ZMScoreCommand#getKey()}
1428+
*
1429+
* @param commands must not be {@literal null}.
1430+
* @return
1431+
* @see <a href="https://redis.io/commands/zmscore">Redis Documentation: ZMSCORE</a>
1432+
* @since 2.6
1433+
*/
1434+
Flux<MultiValueResponse<ZMScoreCommand, Double>> zMScore(Publisher<ZMScoreCommand> commands);
1435+
13421436
/**
13431437
* {@code ZREMRANGEBYRANK} command parameters.
13441438
*
@@ -1787,7 +1881,7 @@ private ZInterStoreCommand(ByteBuffer key, List<ByteBuffer> sourceKeys, List<Dou
17871881
* Creates a new {@link ZInterStoreCommand} given a {@link List} of keys.
17881882
*
17891883
* @param keys must not be {@literal null}.
1790-
* @return a new {@link ZInterStoreCommand} for {@link Range}.
1884+
* @return a new {@link ZInterStoreCommand} for {@link List} of keys.
17911885
*/
17921886
public static ZInterStoreCommand sets(List<ByteBuffer> keys) {
17931887

src/main/java/org/springframework/data/redis/connection/RedisZSetCommands.java

+12
Original file line numberDiff line numberDiff line change
@@ -993,6 +993,18 @@ default Long zCount(byte[] key, double min, double max) {
993993
@Nullable
994994
Double zScore(byte[] key, byte[] value);
995995

996+
/**
997+
* Get the scores of elements with {@code values} from sorted set with key {@code key}.
998+
*
999+
* @param key must not be {@literal null}.
1000+
* @param values the values.
1001+
* @return {@literal null} when used in pipeline / transaction.
1002+
* @see <a href="https://redis.io/commands/zmscore">Redis Documentation: ZMSCORE</a>
1003+
* @since 2.6
1004+
*/
1005+
@Nullable
1006+
List<Double> zMScore(byte[] key, byte[]... values);
1007+
9961008
/**
9971009
* Remove elements in range between {@code start} and {@code end} from sorted set with {@code key}.
9981010
*

src/main/java/org/springframework/data/redis/connection/StringRedisConnection.java

+12
Original file line numberDiff line numberDiff line change
@@ -1432,6 +1432,18 @@ default Long lPos(String key, String element) {
14321432
*/
14331433
Double zScore(String key, String value);
14341434

1435+
/**
1436+
* Get the scores of elements with {@code values} from sorted set with key {@code key}.
1437+
*
1438+
* @param key must not be {@literal null}.
1439+
* @param values the values.
1440+
* @return {@literal null} when used in pipeline / transaction.
1441+
* @see <a href="https://redis.io/commands/zmscore">Redis Documentation: ZMSCORE</a>
1442+
* @see RedisZSetCommands#zMScore(byte[], byte[][])
1443+
* @since 2.6
1444+
*/
1445+
List<Double> zMScore(String key, String... values);
1446+
14351447
/**
14361448
* Remove elements in range between {@code start} and {@code end} from sorted set with {@code key}.
14371449
*

src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterZSetCommands.java

+18
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import redis.clients.jedis.ScanParams;
1919
import redis.clients.jedis.ZParams;
2020

21+
import java.util.List;
2122
import java.util.Set;
2223

2324
import org.springframework.dao.DataAccessException;
@@ -637,6 +638,23 @@ public Double zScore(byte[] key, byte[] value) {
637638
}
638639
}
639640

641+
/*
642+
* (non-Javadoc)
643+
* @see org.springframework.data.redis.connection.RedisZSetCommands#zMScore(byte[], byte[][])
644+
*/
645+
@Override
646+
public List<Double> zMScore(byte[] key, byte[][] values) {
647+
648+
Assert.notNull(key, "Key must not be null!");
649+
Assert.notNull(values, "Values must not be null!");
650+
651+
try {
652+
return connection.getCluster().zmscore(key, values);
653+
} catch (Exception ex) {
654+
throw convertJedisAccessException(ex);
655+
}
656+
}
657+
640658
/*
641659
* (non-Javadoc)
642660
* @see org.springframework.data.redis.connection.RedisZSetCommands#zRemRange(byte[], long, long)

src/main/java/org/springframework/data/redis/connection/jedis/JedisZSetCommands.java

+14-2
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,13 @@
2121
import redis.clients.jedis.ScanParams;
2222
import redis.clients.jedis.ScanResult;
2323
import redis.clients.jedis.ZParams;
24-
import redis.clients.jedis.params.ZAddParams;
2524

2625
import java.nio.charset.StandardCharsets;
2726
import java.util.LinkedHashSet;
27+
import java.util.List;
2828
import java.util.Set;
2929

3030
import org.springframework.data.redis.connection.RedisZSetCommands;
31-
import org.springframework.data.redis.connection.RedisZSetCommands.ZAddArgs.Flag;
3231
import org.springframework.data.redis.core.Cursor;
3332
import org.springframework.data.redis.core.KeyBoundCursor;
3433
import org.springframework.data.redis.core.ScanIteration;
@@ -323,6 +322,19 @@ public Double zScore(byte[] key, byte[] value) {
323322
return connection.invoke().just(BinaryJedis::zscore, MultiKeyPipelineBase::zscore, key, value);
324323
}
325324

325+
/*
326+
* (non-Javadoc)
327+
* @see org.springframework.data.redis.connection.RedisZSetCommands#zScore(byte[], byte[][])
328+
*/
329+
@Override
330+
public List<Double> zMScore(byte[] key, byte[][] values) {
331+
332+
Assert.notNull(key, "Key must not be null!");
333+
Assert.notNull(values, "Value must not be null!");
334+
335+
return connection.invoke().just(BinaryJedis::zmscore, MultiKeyPipelineBase::zmscore, key, values);
336+
}
337+
326338
/*
327339
* (non-Javadoc)
328340
* @see org.springframework.data.redis.connection.RedisZSetCommands#zRemRange(byte[], long, long)

src/main/java/org/springframework/data/redis/connection/lettuce/LettuceConnection.java

+4
Original file line numberDiff line numberDiff line change
@@ -1209,6 +1209,9 @@ static class TypeHints {
12091209
COMMAND_OUTPUT_TYPE_MAPPING.put(ZINCRBY, DoubleOutput.class);
12101210
COMMAND_OUTPUT_TYPE_MAPPING.put(ZSCORE, DoubleOutput.class);
12111211

1212+
// DOUBLE LIST
1213+
COMMAND_OUTPUT_TYPE_MAPPING.put(ZMSCORE, DoubleListOutput.class);
1214+
12121215
// MAP
12131216
COMMAND_OUTPUT_TYPE_MAPPING.put(HGETALL, MapOutput.class);
12141217

@@ -1281,6 +1284,7 @@ static class TypeHints {
12811284
COMMAND_OUTPUT_TYPE_MAPPING.put(HSET, BooleanOutput.class);
12821285
COMMAND_OUTPUT_TYPE_MAPPING.put(HSETNX, BooleanOutput.class);
12831286
COMMAND_OUTPUT_TYPE_MAPPING.put(MOVE, BooleanOutput.class);
1287+
COMMAND_OUTPUT_TYPE_MAPPING.put(COPY, BooleanOutput.class);
12841288
COMMAND_OUTPUT_TYPE_MAPPING.put(MSETNX, BooleanOutput.class);
12851289
COMMAND_OUTPUT_TYPE_MAPPING.put(PERSIST, BooleanOutput.class);
12861290
COMMAND_OUTPUT_TYPE_MAPPING.put(PEXPIRE, BooleanOutput.class);

src/main/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveZSetCommands.java

+19
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,13 @@
2727
import java.util.List;
2828

2929
import org.reactivestreams.Publisher;
30+
3031
import org.springframework.data.domain.Sort.Direction;
3132
import org.springframework.data.redis.connection.DefaultTuple;
3233
import org.springframework.data.redis.connection.ReactiveRedisConnection.CommandResponse;
3334
import org.springframework.data.redis.connection.ReactiveRedisConnection.KeyCommand;
3435
import org.springframework.data.redis.connection.ReactiveRedisConnection.KeyScanCommand;
36+
import org.springframework.data.redis.connection.ReactiveRedisConnection.MultiValueResponse;
3537
import org.springframework.data.redis.connection.ReactiveRedisConnection.NumericResponse;
3638
import org.springframework.data.redis.connection.ReactiveZSetCommands;
3739
import org.springframework.data.redis.connection.RedisZSetCommands.Aggregate;
@@ -381,6 +383,23 @@ public Flux<NumericResponse<ZScoreCommand, Double>> zScore(Publisher<ZScoreComma
381383
}));
382384
}
383385

386+
/*
387+
* (non-Javadoc)
388+
* @see org.springframework.data.redis.connection.ReactiveZSetCommands#zMScore(org.reactivestreams.Publisher)
389+
*/
390+
@Override
391+
public Flux<MultiValueResponse<ZMScoreCommand, Double>> zMScore(Publisher<ZMScoreCommand> commands) {
392+
393+
return connection.execute(cmd -> Flux.from(commands).concatMap(command -> {
394+
395+
Assert.notNull(command.getKey(), "Key must not be null!");
396+
Assert.notNull(command.getValues(), "Values must not be null!");
397+
398+
return cmd.zmscore(command.getKey(), command.getValues().toArray(new ByteBuffer[0]))
399+
.map(value -> new MultiValueResponse<>(command, value));
400+
}));
401+
}
402+
384403
/*
385404
* (non-Javadoc)
386405
* @see org.springframework.data.redis.connection.ReactiveZSetCommands#zRemRangeByRank(org.reactivestreams.Publisher)

src/main/java/org/springframework/data/redis/connection/lettuce/LettuceZSetCommands.java

+13
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,19 @@ public Double zScore(byte[] key, byte[] value) {
302302
return connection.invoke().just(RedisSortedSetAsyncCommands::zscore, key, value);
303303
}
304304

305+
/*
306+
* (non-Javadoc)
307+
* @see org.springframework.data.redis.connection.RedisZSetCommands#zMScore(byte[], byte[][])
308+
*/
309+
@Override
310+
public List<Double> zMScore(byte[] key, byte[][] values) {
311+
312+
Assert.notNull(key, "Key must not be null!");
313+
Assert.notNull(values, "Value must not be null!");
314+
315+
return connection.invoke().just(RedisSortedSetAsyncCommands::zmscore, key, values);
316+
}
317+
305318
/*
306319
* (non-Javadoc)
307320
* @see org.springframework.data.redis.connection.RedisZSetCommands#zRemRange(byte[], long, long)

0 commit comments

Comments
 (0)