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 Original Pull Request: #2088
This commit is contained in:
committed by
Christoph Strobl
parent
c878a933f5
commit
8c743d40ef
@@ -7,7 +7,7 @@ This section briefly covers items that are new and noteworthy in the latest rele
|
||||
== New in Spring Data Redis 2.6
|
||||
|
||||
* 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.
|
||||
* Support Redis 6.2 commands (`LPOP`/`RPOP` with `count`, `COPY`, `GETEX`, `GETDEL`).
|
||||
* Support Redis 6.2 commands (`LPOP`/`RPOP` with `count`, `COPY`, `GETEX`, `GETDEL`, `ZMSCORE`).
|
||||
|
||||
[[new-in-2.5.0]]
|
||||
== New in Spring Data Redis 2.5
|
||||
|
||||
@@ -1722,6 +1722,15 @@ public class DefaultStringRedisConnection implements StringRedisConnection, Deco
|
||||
return convertAndReturn(delegate.zScore(key, value), Converters.identityConverter());
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.RedisZSetCommands#zMScore(byte[], byte[][])
|
||||
*/
|
||||
@Override
|
||||
public List<Double> zMScore(byte[] key, byte[]... values) {
|
||||
return convertAndReturn(delegate.zMScore(key, values), Converters.identityConverter());
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.RedisZSetCommands#zUnionStore(byte[], org.springframework.data.redis.connection.RedisZSetCommands.Aggregate, org.springframework.data.redis.connection.RedisZSetCommands.Weights, byte[][])
|
||||
@@ -3052,6 +3061,15 @@ public class DefaultStringRedisConnection implements StringRedisConnection, Deco
|
||||
return zScore(serialize(key), serialize(value));
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.StringRedisConnection#zMScore(java.lang.String, java.lang.String[])
|
||||
*/
|
||||
@Override
|
||||
public List<Double> zMScore(String key, String... values) {
|
||||
return zMScore(serialize(key), serializeMulti(values));
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.StringRedisConnection#zUnionStore(java.lang.String, org.springframework.data.redis.connection.RedisZSetCommands.Aggregate, int[], java.lang.String[])
|
||||
|
||||
@@ -1103,6 +1103,13 @@ public interface DefaultedRedisConnection extends RedisConnection {
|
||||
return zSetCommands().zScore(key, value);
|
||||
}
|
||||
|
||||
/** @deprecated in favor of {@link RedisConnection#zSetCommands()}}. */
|
||||
@Override
|
||||
@Deprecated
|
||||
default List<Double> zMScore(byte[] key, byte[]... values) {
|
||||
return zSetCommands().zMScore(key, values);
|
||||
}
|
||||
|
||||
/** @deprecated in favor of {@link RedisConnection#zSetCommands()}}. */
|
||||
@Override
|
||||
@Deprecated
|
||||
|
||||
@@ -31,6 +31,7 @@ import org.springframework.data.domain.Sort.Direction;
|
||||
import org.springframework.data.redis.connection.ReactiveRedisConnection.CommandResponse;
|
||||
import org.springframework.data.redis.connection.ReactiveRedisConnection.KeyCommand;
|
||||
import org.springframework.data.redis.connection.ReactiveRedisConnection.KeyScanCommand;
|
||||
import org.springframework.data.redis.connection.ReactiveRedisConnection.MultiValueResponse;
|
||||
import org.springframework.data.redis.connection.ReactiveRedisConnection.NumericResponse;
|
||||
import org.springframework.data.redis.connection.RedisZSetCommands.Aggregate;
|
||||
import org.springframework.data.redis.connection.RedisZSetCommands.Limit;
|
||||
@@ -292,7 +293,7 @@ public interface ReactiveZSetCommands {
|
||||
* Creates a new {@link ZRemCommand} given a {@link Tuple}.
|
||||
*
|
||||
* @param value must not be {@literal null}.
|
||||
* @return a new {@link ZAddCommand} for {@link Tuple}.
|
||||
* @return a new {@link ZRemCommand} for {@link Tuple}.
|
||||
*/
|
||||
public static ZRemCommand values(ByteBuffer value) {
|
||||
|
||||
@@ -305,7 +306,7 @@ public interface ReactiveZSetCommands {
|
||||
* Creates a new {@link ZRemCommand} given a {@link Collection} of {@link Tuple}.
|
||||
*
|
||||
* @param values must not be {@literal null}.
|
||||
* @return a new {@link ZAddCommand} for {@link Tuple}.
|
||||
* @return a new {@link ZRemCommand} for {@link Tuple}.
|
||||
*/
|
||||
public static ZRemCommand values(Collection<ByteBuffer> values) {
|
||||
|
||||
@@ -1283,7 +1284,7 @@ public interface ReactiveZSetCommands {
|
||||
* Creates a new {@link ZScoreCommand} given a {@link ByteBuffer member}.
|
||||
*
|
||||
* @param member must not be {@literal null}.
|
||||
* @return a new {@link ZScoreCommand} for {@link Range}.
|
||||
* @return a new {@link ZScoreCommand} for {@link ByteBuffer member}.
|
||||
*/
|
||||
public static ZScoreCommand scoreOf(ByteBuffer member) {
|
||||
|
||||
@@ -1339,6 +1340,99 @@ public interface ReactiveZSetCommands {
|
||||
*/
|
||||
Flux<NumericResponse<ZScoreCommand, Double>> zScore(Publisher<ZScoreCommand> commands);
|
||||
|
||||
/**
|
||||
* {@code ZMSCORE} command parameters.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @see <a href="https://redis.io/commands/zmscore">Redis Documentation: ZMSCORE</a>
|
||||
* @since 2.6
|
||||
*/
|
||||
class ZMScoreCommand extends KeyCommand {
|
||||
|
||||
private final Collection<ByteBuffer> values;
|
||||
|
||||
private ZMScoreCommand(@Nullable ByteBuffer key, Collection<ByteBuffer> values) {
|
||||
|
||||
super(key);
|
||||
|
||||
this.values = values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link ZMScoreCommand} given a {@link ByteBuffer member}.
|
||||
*
|
||||
* @param member must not be {@literal null}.
|
||||
* @return a new {@link ZMScoreCommand} for {@link ByteBuffer}.
|
||||
*/
|
||||
public static ZMScoreCommand scoreOf(ByteBuffer member) {
|
||||
|
||||
Assert.notNull(member, "Member must not be null!");
|
||||
|
||||
return new ZMScoreCommand(null, Collections.singletonList(member));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link ZMScoreCommand} given a {@link List members}.
|
||||
*
|
||||
* @param member must not be {@literal null}.
|
||||
* @return a new {@link ZMScoreCommand} for {@link List} of members.
|
||||
*/
|
||||
public static ZMScoreCommand scoreOf(Collection<ByteBuffer> members) {
|
||||
|
||||
Assert.notNull(members, "Members must not be null!");
|
||||
|
||||
return new ZMScoreCommand(null, members);
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the {@literal key}. Constructs a new command instance with all previously configured properties.
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @return a new {@link ZMScoreCommand} with {@literal key} applied.
|
||||
*/
|
||||
public ZMScoreCommand forKey(ByteBuffer key) {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
return new ZMScoreCommand(key, values);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public Collection<ByteBuffer> getValues() {
|
||||
return values;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the scores of elements with {@literal values} from sorted set with key {@literal key}.
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @param values must not be {@literal null}.
|
||||
* @return
|
||||
* @see <a href="https://redis.io/commands/zmscore">Redis Documentation: ZMSCORE</a>
|
||||
* @since 2.6
|
||||
*/
|
||||
default Mono<List<Double>> zMScore(ByteBuffer key, Collection<ByteBuffer> values) {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
Assert.notNull(values, "Values must not be null!");
|
||||
|
||||
return zMScore(Mono.just(ZMScoreCommand.scoreOf(values).forKey(key))).next().map(MultiValueResponse::getOutput);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the scores of elements with {@link ZMScoreCommand#getValues()} from sorted set with key
|
||||
* {@link ZMScoreCommand#getKey()}
|
||||
*
|
||||
* @param commands must not be {@literal null}.
|
||||
* @return
|
||||
* @see <a href="https://redis.io/commands/zmscore">Redis Documentation: ZMSCORE</a>
|
||||
* @since 2.6
|
||||
*/
|
||||
Flux<MultiValueResponse<ZMScoreCommand, Double>> zMScore(Publisher<ZMScoreCommand> commands);
|
||||
|
||||
/**
|
||||
* {@code ZREMRANGEBYRANK} command parameters.
|
||||
*
|
||||
@@ -1787,7 +1881,7 @@ public interface ReactiveZSetCommands {
|
||||
* Creates a new {@link ZInterStoreCommand} given a {@link List} of keys.
|
||||
*
|
||||
* @param keys must not be {@literal null}.
|
||||
* @return a new {@link ZInterStoreCommand} for {@link Range}.
|
||||
* @return a new {@link ZInterStoreCommand} for {@link List} of keys.
|
||||
*/
|
||||
public static ZInterStoreCommand sets(List<ByteBuffer> keys) {
|
||||
|
||||
|
||||
@@ -993,6 +993,18 @@ public interface RedisZSetCommands {
|
||||
@Nullable
|
||||
Double zScore(byte[] key, byte[] value);
|
||||
|
||||
/**
|
||||
* Get the scores of elements with {@code values} from sorted set with key {@code key}.
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @param values the values.
|
||||
* @return {@literal null} when used in pipeline / transaction.
|
||||
* @see <a href="https://redis.io/commands/zmscore">Redis Documentation: ZMSCORE</a>
|
||||
* @since 2.6
|
||||
*/
|
||||
@Nullable
|
||||
List<Double> zMScore(byte[] key, byte[]... values);
|
||||
|
||||
/**
|
||||
* Remove elements in range between {@code start} and {@code end} from sorted set with {@code key}.
|
||||
*
|
||||
|
||||
@@ -1455,6 +1455,18 @@ public interface StringRedisConnection extends RedisConnection {
|
||||
*/
|
||||
Double zScore(String key, String value);
|
||||
|
||||
/**
|
||||
* Get the scores of elements with {@code values} from sorted set with key {@code key}.
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @param values the values.
|
||||
* @return {@literal null} when used in pipeline / transaction.
|
||||
* @see <a href="https://redis.io/commands/zmscore">Redis Documentation: ZMSCORE</a>
|
||||
* @see RedisZSetCommands#zMScore(byte[], byte[][])
|
||||
* @since 2.6
|
||||
*/
|
||||
List<Double> zMScore(String key, String... values);
|
||||
|
||||
/**
|
||||
* Remove elements in range between {@code start} and {@code end} from sorted set with {@code key}.
|
||||
*
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.springframework.data.redis.connection.jedis;
|
||||
import redis.clients.jedis.ScanParams;
|
||||
import redis.clients.jedis.ZParams;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.dao.DataAccessException;
|
||||
@@ -637,6 +638,23 @@ class JedisClusterZSetCommands implements RedisZSetCommands {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.RedisZSetCommands#zMScore(byte[], byte[][])
|
||||
*/
|
||||
@Override
|
||||
public List<Double> zMScore(byte[] key, byte[][] values) {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
Assert.notNull(values, "Values must not be null!");
|
||||
|
||||
try {
|
||||
return connection.getCluster().zmscore(key, values);
|
||||
} catch (Exception ex) {
|
||||
throw convertJedisAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.RedisZSetCommands#zRemRange(byte[], long, long)
|
||||
|
||||
@@ -21,14 +21,13 @@ import redis.clients.jedis.MultiKeyPipelineBase;
|
||||
import redis.clients.jedis.ScanParams;
|
||||
import redis.clients.jedis.ScanResult;
|
||||
import redis.clients.jedis.ZParams;
|
||||
import redis.clients.jedis.params.ZAddParams;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.data.redis.connection.RedisZSetCommands;
|
||||
import org.springframework.data.redis.connection.RedisZSetCommands.ZAddArgs.Flag;
|
||||
import org.springframework.data.redis.core.Cursor;
|
||||
import org.springframework.data.redis.core.KeyBoundCursor;
|
||||
import org.springframework.data.redis.core.ScanIteration;
|
||||
@@ -323,6 +322,19 @@ class JedisZSetCommands implements RedisZSetCommands {
|
||||
return connection.invoke().just(BinaryJedis::zscore, MultiKeyPipelineBase::zscore, key, value);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.RedisZSetCommands#zScore(byte[], byte[][])
|
||||
*/
|
||||
@Override
|
||||
public List<Double> zMScore(byte[] key, byte[][] values) {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
Assert.notNull(values, "Value must not be null!");
|
||||
|
||||
return connection.invoke().just(BinaryJedis::zmscore, MultiKeyPipelineBase::zmscore, key, values);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.RedisZSetCommands#zRemRange(byte[], long, long)
|
||||
|
||||
@@ -1209,6 +1209,9 @@ public class LettuceConnection extends AbstractRedisConnection {
|
||||
COMMAND_OUTPUT_TYPE_MAPPING.put(ZINCRBY, DoubleOutput.class);
|
||||
COMMAND_OUTPUT_TYPE_MAPPING.put(ZSCORE, DoubleOutput.class);
|
||||
|
||||
// DOUBLE LIST
|
||||
COMMAND_OUTPUT_TYPE_MAPPING.put(ZMSCORE, DoubleListOutput.class);
|
||||
|
||||
// MAP
|
||||
COMMAND_OUTPUT_TYPE_MAPPING.put(HGETALL, MapOutput.class);
|
||||
|
||||
@@ -1281,6 +1284,7 @@ public class LettuceConnection extends AbstractRedisConnection {
|
||||
COMMAND_OUTPUT_TYPE_MAPPING.put(HSET, BooleanOutput.class);
|
||||
COMMAND_OUTPUT_TYPE_MAPPING.put(HSETNX, BooleanOutput.class);
|
||||
COMMAND_OUTPUT_TYPE_MAPPING.put(MOVE, BooleanOutput.class);
|
||||
COMMAND_OUTPUT_TYPE_MAPPING.put(COPY, BooleanOutput.class);
|
||||
COMMAND_OUTPUT_TYPE_MAPPING.put(MSETNX, BooleanOutput.class);
|
||||
COMMAND_OUTPUT_TYPE_MAPPING.put(PERSIST, BooleanOutput.class);
|
||||
COMMAND_OUTPUT_TYPE_MAPPING.put(PEXPIRE, BooleanOutput.class);
|
||||
|
||||
@@ -27,11 +27,13 @@ import java.nio.ByteBuffer;
|
||||
import java.util.List;
|
||||
|
||||
import org.reactivestreams.Publisher;
|
||||
|
||||
import org.springframework.data.domain.Sort.Direction;
|
||||
import org.springframework.data.redis.connection.DefaultTuple;
|
||||
import org.springframework.data.redis.connection.ReactiveRedisConnection.CommandResponse;
|
||||
import org.springframework.data.redis.connection.ReactiveRedisConnection.KeyCommand;
|
||||
import org.springframework.data.redis.connection.ReactiveRedisConnection.KeyScanCommand;
|
||||
import org.springframework.data.redis.connection.ReactiveRedisConnection.MultiValueResponse;
|
||||
import org.springframework.data.redis.connection.ReactiveRedisConnection.NumericResponse;
|
||||
import org.springframework.data.redis.connection.ReactiveZSetCommands;
|
||||
import org.springframework.data.redis.connection.RedisZSetCommands.Aggregate;
|
||||
@@ -381,6 +383,23 @@ class LettuceReactiveZSetCommands implements ReactiveZSetCommands {
|
||||
}));
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.ReactiveZSetCommands#zMScore(org.reactivestreams.Publisher)
|
||||
*/
|
||||
@Override
|
||||
public Flux<MultiValueResponse<ZMScoreCommand, Double>> zMScore(Publisher<ZMScoreCommand> commands) {
|
||||
|
||||
return connection.execute(cmd -> Flux.from(commands).concatMap(command -> {
|
||||
|
||||
Assert.notNull(command.getKey(), "Key must not be null!");
|
||||
Assert.notNull(command.getValues(), "Values must not be null!");
|
||||
|
||||
return cmd.zmscore(command.getKey(), command.getValues().toArray(new ByteBuffer[0]))
|
||||
.map(value -> new MultiValueResponse<>(command, value));
|
||||
}));
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.ReactiveZSetCommands#zRemRangeByRank(org.reactivestreams.Publisher)
|
||||
|
||||
@@ -302,6 +302,19 @@ class LettuceZSetCommands implements RedisZSetCommands {
|
||||
return connection.invoke().just(RedisSortedSetAsyncCommands::zscore, key, value);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.RedisZSetCommands#zMScore(byte[], byte[][])
|
||||
*/
|
||||
@Override
|
||||
public List<Double> zMScore(byte[] key, byte[][] values) {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
Assert.notNull(values, "Value must not be null!");
|
||||
|
||||
return connection.invoke().just(RedisSortedSetAsyncCommands::zmscore, key, values);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.RedisZSetCommands#zRemRange(byte[], long, long)
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package org.springframework.data.redis.core;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.data.redis.connection.RedisZSetCommands.Aggregate;
|
||||
@@ -264,6 +265,17 @@ public interface BoundZSetOperations<K, V> extends BoundKeyOperations<K> {
|
||||
@Nullable
|
||||
Double score(Object o);
|
||||
|
||||
/**
|
||||
* Get the scores of elements with {@code values} from sorted set with key the bound key.
|
||||
*
|
||||
* @param o the values.
|
||||
* @return {@literal null} when used in pipeline / transaction.
|
||||
* @see <a href="https://redis.io/commands/zmscore">Redis Documentation: ZMSCORE</a>
|
||||
* @since 2.6
|
||||
*/
|
||||
@Nullable
|
||||
List<Double> score(Object... o);
|
||||
|
||||
/**
|
||||
* Remove elements in range between {@code start} and {@code end} from sorted set with the bound key.
|
||||
*
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.springframework.data.redis.core;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.data.redis.connection.DataType;
|
||||
@@ -249,6 +250,15 @@ class DefaultBoundZSetOperations<K, V> extends DefaultBoundKeyOperations<K> impl
|
||||
return ops.score(getKey(), o);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.core.BoundZSetOperations#score(java.lang.Object[])
|
||||
*/
|
||||
@Override
|
||||
public List<Double> score(Object... o) {
|
||||
return ops.score(getKey(), o);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.core.BoundZSetOperations#remove(java.lang.Object[])
|
||||
|
||||
@@ -370,6 +370,22 @@ class DefaultReactiveZSetOperations<K, V> implements ReactiveZSetOperations<K, V
|
||||
return createMono(connection -> connection.zScore(rawKey(key), rawValue((V) o)));
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.core.ReactiveZSetOperations#score(java.lang.Object, java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Mono<List<Double>> score(K key, Object... o) {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
return createMono(connection -> Flux.fromArray((V[]) o) //
|
||||
.map(this::rawValue) //
|
||||
.collectList() //
|
||||
.flatMap(values -> connection.zMScore(rawKey(key), values)));
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.core.ReactiveZSetOperations#removeRange(java.lang.Object, org.springframework.data.domain.Range)
|
||||
|
||||
@@ -17,6 +17,7 @@ package org.springframework.data.redis.core;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.data.redis.connection.RedisZSetCommands.Aggregate;
|
||||
@@ -437,6 +438,18 @@ class DefaultZSetOperations<K, V> extends AbstractOperations<K, V> implements ZS
|
||||
return execute(connection -> connection.zScore(rawKey, rawValue), true);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.core.ZSetOperations#score(java.lang.Object, java.lang.Object[])
|
||||
*/
|
||||
@Override
|
||||
public List<Double> score(K key, Object... o) {
|
||||
|
||||
byte[] rawKey = rawKey(key);
|
||||
byte[][] rawValues = rawValues(o);
|
||||
return execute(connection -> connection.zMScore(rawKey, rawValues), true);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.core.ZSetOperations#count(java.lang.Object, double, double)
|
||||
|
||||
@@ -19,6 +19,7 @@ import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.domain.Range;
|
||||
import org.springframework.data.redis.connection.RedisZSetCommands.Aggregate;
|
||||
@@ -300,6 +301,17 @@ public interface ReactiveZSetOperations<K, V> {
|
||||
*/
|
||||
Mono<Double> score(K key, Object o);
|
||||
|
||||
/**
|
||||
* Get the scores of elements with {@code values} from sorted set with key {@code key}.
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @param o the values.
|
||||
* @return
|
||||
* @see <a href="https://redis.io/commands/zmscore">Redis Documentation: ZMSCORE</a>
|
||||
* @since 2.6
|
||||
*/
|
||||
Mono<List<Double>> score(K key, Object... o);
|
||||
|
||||
/**
|
||||
* Remove elements in range between {@code start} and {@code end} from sorted set with {@code key}.
|
||||
*
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package org.springframework.data.redis.core;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.data.redis.connection.RedisZSetCommands.Aggregate;
|
||||
@@ -370,6 +371,18 @@ public interface ZSetOperations<K, V> {
|
||||
@Nullable
|
||||
Double score(K key, Object o);
|
||||
|
||||
/**
|
||||
* Get the scores of elements with {@code values} from sorted set with key {@code key}.
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @param o the values.
|
||||
* @return {@literal null} when used in pipeline / transaction.
|
||||
* @see <a href="https://redis.io/commands/zmscore">Redis Documentation: ZMSCORE</a>
|
||||
* @since 2.6
|
||||
*/
|
||||
@Nullable
|
||||
List<Double> score(K key, Object... o);
|
||||
|
||||
/**
|
||||
* Remove elements in range between {@code start} and {@code end} from sorted set with {@code key}.
|
||||
*
|
||||
|
||||
@@ -2054,6 +2054,16 @@ public abstract class AbstractConnectionIntegrationTests {
|
||||
verifyResults(Arrays.asList(new Object[] { true, true, true, 3d }));
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnabledOnCommand("ZMSCORE")
|
||||
void testZMScore() {
|
||||
actual.add(connection.zAdd("myset", 2, "Bob"));
|
||||
actual.add(connection.zAdd("myset", 1, "James"));
|
||||
actual.add(connection.zAdd("myset", 3, "Joe"));
|
||||
actual.add(connection.zMScore("myset", "James", "Joe"));
|
||||
verifyResults(Arrays.asList(new Object[] { true, true, true, Arrays.asList(1d, 3d) }));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testZUnionStore() {
|
||||
actual.add(connection.zAdd("myset", 2, "Bob"));
|
||||
|
||||
@@ -670,6 +670,9 @@ public interface ClusterConnectionTests {
|
||||
// DATAREDIS-315
|
||||
void zScoreShouldRetrieveScoreForValue();
|
||||
|
||||
// GH-2038
|
||||
void zMScoreShouldRetrieveScoreForValues();
|
||||
|
||||
// DATAREDIS-315
|
||||
void zUnionStoreShouldThrowExceptionWhenKeysDoNotMapToSameSlots();
|
||||
|
||||
|
||||
@@ -1330,6 +1330,12 @@ public class DefaultStringRedisConnectionPipelineTests extends DefaultStringRedi
|
||||
super.testZScore();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testZMScore() {
|
||||
doReturn(Collections.singletonList(Arrays.asList(1d, 3d))).when(nativeConnection).closePipeline();
|
||||
super.testZMScore();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testZUnionStoreAggWeightsBytes() {
|
||||
doReturn(Collections.singletonList(5L)).when(nativeConnection).closePipeline();
|
||||
|
||||
@@ -1433,6 +1433,13 @@ public class DefaultStringRedisConnectionPipelineTxTests extends DefaultStringRe
|
||||
super.testZScore();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testZMScore() {
|
||||
doReturn(Collections.singletonList(Collections.singletonList(Arrays.asList(1d, 3d)))).when(nativeConnection)
|
||||
.closePipeline();
|
||||
super.testZMScore();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testZUnionStoreAggWeightsBytes() {
|
||||
doReturn(Collections.singletonList(Collections.singletonList(5L))).when(nativeConnection).closePipeline();
|
||||
|
||||
@@ -1624,6 +1624,13 @@ public class DefaultStringRedisConnectionTests {
|
||||
verifyResults(Collections.singletonList(3d));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testZMScore() {
|
||||
doReturn(Arrays.asList(1d, 3d)).when(nativeConnection).zMScore(fooBytes, barBytes, bar2Bytes);
|
||||
actual.add(connection.zMScore(foo, bar, bar2));
|
||||
verifyResults(Collections.singletonList(Arrays.asList(1d, 3d)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testZUnionStoreAggWeightsBytes() {
|
||||
doReturn(5L).when(nativeConnection).zUnionStore(eq(fooBytes), eq(Aggregate.MAX), any(Weights.class), eq(fooBytes));
|
||||
|
||||
@@ -1316,6 +1316,12 @@ public class DefaultStringRedisConnectionTxTests extends DefaultStringRedisConne
|
||||
super.testZScore();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testZMScore() {
|
||||
doReturn(Collections.singletonList(Arrays.asList(1d, 3d))).when(nativeConnection).exec();
|
||||
super.testZMScore();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testZUnionStoreAggWeightsBytes() {
|
||||
doReturn(Collections.singletonList(5L)).when(nativeConnection).exec();
|
||||
|
||||
@@ -833,6 +833,10 @@ class RedisConnectionUnitTests {
|
||||
return delegate.zScore(key, value);
|
||||
}
|
||||
|
||||
public List<Double> zMScore(byte[] key, byte[][] values) {
|
||||
return delegate.zMScore(key, values);
|
||||
}
|
||||
|
||||
public Long zRemRange(byte[] key, long begin, long end) {
|
||||
return delegate.zRemRange(key, begin, end);
|
||||
}
|
||||
|
||||
@@ -2304,6 +2304,16 @@ public class JedisClusterConnectionTests implements ClusterConnectionTests {
|
||||
assertThat(clusterConnection.zScore(KEY_1_BYTES, VALUE_2_BYTES)).isEqualTo(20D);
|
||||
}
|
||||
|
||||
@Test // GH-2038
|
||||
@EnabledOnCommand("ZMSCORE")
|
||||
public void zMScoreShouldRetrieveScoreForValues() {
|
||||
|
||||
nativeConnection.zadd(KEY_1_BYTES, 10D, VALUE_1_BYTES);
|
||||
nativeConnection.zadd(KEY_1_BYTES, 20D, VALUE_2_BYTES);
|
||||
|
||||
assertThat(clusterConnection.zMScore(KEY_1_BYTES, VALUE_1_BYTES, VALUE_2_BYTES)).containsSequence(10D, 20D);
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-315
|
||||
public void zUnionStoreShouldThrowExceptionWhenKeysDoNotMapToSameSlots() {
|
||||
assertThatExceptionOfType(DataAccessException.class)
|
||||
|
||||
@@ -2345,6 +2345,16 @@ public class LettuceClusterConnectionTests implements ClusterConnectionTests {
|
||||
assertThat(clusterConnection.zScore(KEY_1_BYTES, VALUE_2_BYTES)).isEqualTo(20D);
|
||||
}
|
||||
|
||||
@Test // GH-2038
|
||||
@EnabledOnCommand("ZMSCORE")
|
||||
public void zMScoreShouldRetrieveScoreForValues() {
|
||||
|
||||
nativeConnection.zadd(KEY_1, 10D, VALUE_1);
|
||||
nativeConnection.zadd(KEY_1, 20D, VALUE_2);
|
||||
|
||||
assertThat(clusterConnection.zMScore(KEY_1_BYTES, VALUE_1_BYTES, VALUE_2_BYTES)).containsExactly(10D, 20D);
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-315
|
||||
public void zUnionStoreShouldThrowExceptionWhenKeysDoNotMapToSameSlots() {
|
||||
assertThatExceptionOfType(DataAccessException.class)
|
||||
|
||||
@@ -27,6 +27,7 @@ import java.util.Arrays;
|
||||
import org.springframework.data.domain.Range;
|
||||
import org.springframework.data.redis.connection.DefaultTuple;
|
||||
import org.springframework.data.redis.core.ScanOptions;
|
||||
import org.springframework.data.redis.test.condition.EnabledOnCommand;
|
||||
import org.springframework.data.redis.test.extension.parametrized.ParameterizedRedisTest;
|
||||
|
||||
/**
|
||||
@@ -402,6 +403,17 @@ public class LettuceReactiveZSetCommandsIntegrationTests extends LettuceReactive
|
||||
assertThat(connection.zSetCommands().zScore(KEY_1_BBUFFER, VALUE_2_BBUFFER).block()).isEqualTo(2D);
|
||||
}
|
||||
|
||||
@ParameterizedRedisTest // GH-2038
|
||||
@EnabledOnCommand("ZMSCORE")
|
||||
void zMScoreShouldReturnScoreCorrectly() {
|
||||
|
||||
nativeCommands.zadd(KEY_1, 1D, VALUE_1);
|
||||
nativeCommands.zadd(KEY_1, 2D, VALUE_2);
|
||||
|
||||
connection.zSetCommands().zMScore(KEY_1_BBUFFER, Arrays.asList(VALUE_1_BBUFFER, VALUE_2_BBUFFER))
|
||||
.as(StepVerifier::create).expectNext(Arrays.asList(1D, 2D)).verifyComplete();
|
||||
}
|
||||
|
||||
@ParameterizedRedisTest // DATAREDIS-525
|
||||
void zRemRangeByRankShouldRemoveValuesCorrectly() {
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ import org.springframework.data.redis.connection.RedisZSetCommands.Weights;
|
||||
import org.springframework.data.redis.core.ReactiveOperationsTestParams.Fixture;
|
||||
import org.springframework.data.redis.serializer.RedisSerializer;
|
||||
import org.springframework.data.redis.serializer.StringRedisSerializer;
|
||||
import org.springframework.data.redis.test.condition.EnabledOnCommand;
|
||||
import org.springframework.data.redis.test.extension.parametrized.MethodSource;
|
||||
import org.springframework.data.redis.test.extension.parametrized.ParameterizedRedisTest;
|
||||
|
||||
@@ -460,6 +461,21 @@ public class DefaultReactiveZSetOperationsIntegrationTests<K, V> {
|
||||
zSetOperations.score(key, value2).as(StepVerifier::create).expectNext(10d).verifyComplete();
|
||||
}
|
||||
|
||||
@ParameterizedRedisTest // GH-2038
|
||||
@EnabledOnCommand("ZMSCORE")
|
||||
void scores() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value1 = valueFactory.instance();
|
||||
V value2 = valueFactory.instance();
|
||||
|
||||
zSetOperations.add(key, value1, 42.1).as(StepVerifier::create).expectNext(true).verifyComplete();
|
||||
zSetOperations.add(key, value2, 10).as(StepVerifier::create).expectNext(true).verifyComplete();
|
||||
|
||||
zSetOperations.score(key, value1, value2, valueFactory.instance()).as(StepVerifier::create)
|
||||
.expectNext(Arrays.asList(42.1d, 10d, null)).verifyComplete();
|
||||
}
|
||||
|
||||
@ParameterizedRedisTest // DATAREDIS-602
|
||||
void removeRange() {
|
||||
|
||||
|
||||
@@ -339,6 +339,21 @@ public class DefaultZSetOperationsIntegrationTests<K, V> {
|
||||
assertThat(zSetOps.range(key, 0, -1)).containsOnly(value2);
|
||||
}
|
||||
|
||||
@ParameterizedRedisTest
|
||||
void testScore() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value1 = valueFactory.instance();
|
||||
V value2 = valueFactory.instance();
|
||||
V value3 = valueFactory.instance();
|
||||
|
||||
zSetOps.add(key, value1, 1.9);
|
||||
zSetOps.add(key, value2, 3.7);
|
||||
zSetOps.add(key, value3, 5.8);
|
||||
|
||||
assertThat(zSetOps.score(key, value1, value2, valueFactory.instance())).containsExactly(1.9d, 3.7d, null);
|
||||
}
|
||||
|
||||
@ParameterizedRedisTest
|
||||
void zCardRetrievesDataCorrectly() {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user