committed by
Christoph Strobl
parent
961ba9035d
commit
0b8fbae2c3
@@ -106,6 +106,26 @@ public class DefaultStringRedisConnection implements StringRedisConnection, Deco
|
||||
@SuppressWarnings("rawtypes") private Queue<Converter> txConverters = new LinkedList<>();
|
||||
private boolean deserializePipelineAndTxResults = false;
|
||||
|
||||
private Entry<String, String> convertEntry(Entry<byte[], byte[]> source) {
|
||||
return new Entry<String, String>() {
|
||||
|
||||
@Override
|
||||
public String getKey() {
|
||||
return bytesToString.convert(source.getKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getValue() {
|
||||
return bytesToString.convert(source.getValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String setValue(String value) {
|
||||
throw new UnsupportedOperationException("Cannot set value for entry");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private class DeserializingConverter implements Converter<byte[], String> {
|
||||
public String convert(byte[] source) {
|
||||
return serializer.deserialize(source);
|
||||
@@ -2307,6 +2327,88 @@ public class DefaultStringRedisConnection implements StringRedisConnection, Deco
|
||||
return hIncrBy(serialize(key), serialize(field), delta);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.RedisHashCommands#hRandField(byte[])
|
||||
*/
|
||||
@Nullable
|
||||
@Override
|
||||
public byte[] hRandField(byte[] key) {
|
||||
return convertAndReturn(delegate.hRandField(key), Converters.identityConverter());
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.RedisHashCommands#hRandFieldWithValues(byte[])
|
||||
*/
|
||||
@Nullable
|
||||
@Override
|
||||
public Entry<byte[], byte[]> hRandFieldWithValues(byte[] key) {
|
||||
return convertAndReturn(delegate.hRandFieldWithValues(key), Converters.identityConverter());
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.RedisHashCommands#hRandField(byte[], long)
|
||||
*/
|
||||
@Nullable
|
||||
@Override
|
||||
public List<byte[]> hRandField(byte[] key, long count) {
|
||||
return convertAndReturn(delegate.hRandField(key, count), Converters.identityConverter());
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.RedisHashCommands#hRandFieldWithValues(byte[], long)
|
||||
*/
|
||||
@Nullable
|
||||
@Override
|
||||
public List<Entry<byte[], byte[]>> hRandFieldWithValues(byte[] key, long count) {
|
||||
return convertAndReturn(delegate.hRandFieldWithValues(key, count), Converters.identityConverter());
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.StringRedisConnection#hRandField(java.lang.String)
|
||||
*/
|
||||
@Nullable
|
||||
@Override
|
||||
public String hRandField(String key) {
|
||||
return convertAndReturn(delegate.hRandField(serialize(key)), bytesToString);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.StringRedisConnection#hRandFieldWithValues(java.lang.String)
|
||||
*/
|
||||
@Nullable
|
||||
@Override
|
||||
public Entry<String, String> hRandFieldWithValues(String key) {
|
||||
return convertAndReturn(delegate.hRandFieldWithValues(serialize(key)),
|
||||
(Converter<Entry<byte[], byte[]>, Entry<String, String>>) this::convertEntry);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.StringRedisConnection#hRandField(java.lang.String, long)
|
||||
*/
|
||||
@Nullable
|
||||
@Override
|
||||
public List<String> hRandField(String key, long count) {
|
||||
return convertAndReturn(delegate.hRandField(serialize(key), count), byteListToStringList);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.StringRedisConnection#hRandFieldWithValues(java.lang.String, long)
|
||||
*/
|
||||
@Nullable
|
||||
@Override
|
||||
public List<Entry<String, String>> hRandFieldWithValues(String key, long count) {
|
||||
return convertAndReturn(delegate.hRandFieldWithValues(serialize(key), count),
|
||||
new ListConverter<>(this::convertEntry));
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.StringRedisConnection#hKeys(java.lang.String)
|
||||
@@ -3924,24 +4026,7 @@ public class DefaultStringRedisConnection implements StringRedisConnection, Deco
|
||||
@Override
|
||||
public Cursor<Entry<String, String>> hScan(String key, ScanOptions options) {
|
||||
|
||||
return new ConvertingCursor<>(this.delegate.hScan(this.serialize(key), options),
|
||||
source -> new Entry<String, String>() {
|
||||
|
||||
@Override
|
||||
public String getKey() {
|
||||
return bytesToString.convert(source.getKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getValue() {
|
||||
return bytesToString.convert(source.getValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String setValue(String value) {
|
||||
throw new UnsupportedOperationException("Cannot set value for entry in cursor");
|
||||
}
|
||||
});
|
||||
return new ConvertingCursor<>(this.delegate.hScan(this.serialize(key), options), this::convertEntry);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -1329,6 +1329,34 @@ public interface DefaultedRedisConnection extends RedisConnection {
|
||||
return hashCommands().hIncrBy(key, field, delta);
|
||||
}
|
||||
|
||||
/** @deprecated in favor of {@link RedisConnection#hashCommands()}}. */
|
||||
@Override
|
||||
@Deprecated
|
||||
default byte[] hRandField(byte[] key) {
|
||||
return hashCommands().hRandField(key);
|
||||
}
|
||||
|
||||
/** @deprecated in favor of {@link RedisConnection#hashCommands()}}. */
|
||||
@Override
|
||||
@Deprecated
|
||||
default Entry<byte[], byte[]> hRandFieldWithValues(byte[] key) {
|
||||
return hashCommands().hRandFieldWithValues(key);
|
||||
}
|
||||
|
||||
/** @deprecated in favor of {@link RedisConnection#hashCommands()}}. */
|
||||
@Override
|
||||
@Deprecated
|
||||
default List<byte[]> hRandField(byte[] key, long count) {
|
||||
return hashCommands().hRandField(key, count);
|
||||
}
|
||||
|
||||
/** @deprecated in favor of {@link RedisConnection#hashCommands()}}. */
|
||||
@Override
|
||||
@Deprecated
|
||||
default List<Entry<byte[], byte[]>> hRandFieldWithValues(byte[] key, long count) {
|
||||
return hashCommands().hRandFieldWithValues(key, count);
|
||||
}
|
||||
|
||||
/** @deprecated in favor of {@link RedisConnection#hashCommands()}}. */
|
||||
@Override
|
||||
@Deprecated
|
||||
|
||||
@@ -512,6 +512,145 @@ public interface ReactiveHashCommands {
|
||||
*/
|
||||
Flux<NumericResponse<KeyCommand, Long>> hLen(Publisher<KeyCommand> commands);
|
||||
|
||||
/**
|
||||
* {@literal HRANDFIELD} {@link Command}.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @since 2.6
|
||||
* @see <a href="https://redis.io/commands/hrandfield">Redis Documentation: HRANDFIELD</a>
|
||||
*/
|
||||
class HRandFieldCommand extends KeyCommand {
|
||||
|
||||
private long count;
|
||||
|
||||
private HRandFieldCommand(@Nullable ByteBuffer key, long count) {
|
||||
|
||||
super(key);
|
||||
|
||||
this.count = count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the hash {@literal key}. Constructs a new command instance with all previously configured properties.
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @return a new {@link HRandFieldCommand} with {@literal key} applied.
|
||||
*/
|
||||
public static HRandFieldCommand key(ByteBuffer key) {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
return new HRandFieldCommand(key, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the {@literal count}. Constructs a new command instance with all previously configured properties. If the
|
||||
* provided {@code count} argument is positive, return a list of distinct fields, capped either at {@code count} or
|
||||
* the hash size. If {@code count} is negative, the behavior changes and the command is allowed to return the same
|
||||
* field multiple times. In this case, the number of returned fields is the absolute value of the specified count.
|
||||
*
|
||||
* @param count
|
||||
* @return a new {@link HRandFieldCommand} with {@literal key} applied.
|
||||
*/
|
||||
public HRandFieldCommand count(long count) {
|
||||
return new HRandFieldCommand(getKey(), count);
|
||||
}
|
||||
|
||||
public long getCount() {
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a random field from the hash value stored at {@code key}.
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @return
|
||||
* @since 2.6
|
||||
* @see <a href="https://redis.io/commands/hrandfield">Redis Documentation: HRANDFIELD</a>
|
||||
*/
|
||||
default Mono<ByteBuffer> hRandField(ByteBuffer key) {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
return hRandField(Mono.just(HRandFieldCommand.key(key).count(1))).flatMap(CommandResponse::getOutput).next();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a random field from the hash value stored at {@code key}.
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @return
|
||||
* @since 2.6
|
||||
* @see <a href="https://redis.io/commands/hrandfield">Redis Documentation: HRANDFIELD</a>
|
||||
*/
|
||||
default Mono<Map.Entry<ByteBuffer, ByteBuffer>> hRandFieldWithValues(ByteBuffer key) {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
return hRandFieldWithValues(Mono.just(HRandFieldCommand.key(key).count(1))).flatMap(CommandResponse::getOutput)
|
||||
.next();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a random field from the hash value stored at {@code key}. If the provided {@code count} argument is
|
||||
* positive, return a list of distinct fields, capped either at {@code count} or the hash size. If {@code count} is
|
||||
* negative, the behavior changes and the command is allowed to return the same field multiple times. In this case,
|
||||
* the number of returned fields is the absolute value of the specified count.
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @param count number of fields to return.
|
||||
* @return
|
||||
* @since 2.6
|
||||
* @see <a href="https://redis.io/commands/hrandfield">Redis Documentation: HRANDFIELD</a>
|
||||
*/
|
||||
default Flux<ByteBuffer> hRandField(ByteBuffer key, long count) {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
return hRandField(Mono.just(HRandFieldCommand.key(key).count(count))).flatMap(CommandResponse::getOutput);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a random field from the hash value stored at {@code key}. If the provided {@code count} argument is
|
||||
* positive, return a list of distinct fields, capped either at {@code count} or the hash size. If {@code count} is
|
||||
* negative, the behavior changes and the command is allowed to return the same field multiple times. In this case,
|
||||
* the number of returned fields is the absolute value of the specified count.
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @param count number of fields to return.
|
||||
* @return {@literal null} if key does not exist or when used in pipeline / transaction.
|
||||
* @since 2.6
|
||||
* @see <a href="https://redis.io/commands/hrandfield">Redis Documentation: HRANDFIELD</a>
|
||||
*/
|
||||
default Flux<Map.Entry<ByteBuffer, ByteBuffer>> hRandFieldWithValues(ByteBuffer key, long count) {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
return hRandFieldWithValues(Mono.just(HRandFieldCommand.key(key).count(count))).flatMap(CommandResponse::getOutput);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get random fields of hash at {@literal key}.
|
||||
*
|
||||
* @param commands must not be {@literal null}.
|
||||
* @return
|
||||
* @since 2.6
|
||||
* @see <a href="https://redis.io/commands/hrandfield">Redis Documentation: HRANDFIELD</a>
|
||||
*/
|
||||
Flux<CommandResponse<HRandFieldCommand, Flux<ByteBuffer>>> hRandField(Publisher<HRandFieldCommand> commands);
|
||||
|
||||
/**
|
||||
* Get random fields along their values of hash at {@literal key}.
|
||||
*
|
||||
* @param commands must not be {@literal null}.
|
||||
* @return
|
||||
* @since 2.6
|
||||
* @see <a href="https://redis.io/commands/hrandfield">Redis Documentation: HRANDFIELD</a>
|
||||
*/
|
||||
Flux<CommandResponse<HRandFieldCommand, Flux<Map.Entry<ByteBuffer, ByteBuffer>>>> hRandFieldWithValues(
|
||||
Publisher<HRandFieldCommand> commands);
|
||||
|
||||
/**
|
||||
* Get key set (fields) of hash at {@literal key}.
|
||||
*
|
||||
|
||||
@@ -173,6 +173,58 @@ public interface RedisHashCommands {
|
||||
@Nullable
|
||||
Map<byte[], byte[]> hGetAll(byte[] key);
|
||||
|
||||
/**
|
||||
* Return a random field from the hash value stored at {@code key}.
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @return {@literal null} if key does not exist or when used in pipeline / transaction.
|
||||
* @since 2.6
|
||||
* @see <a href="https://redis.io/commands/hrandfield">Redis Documentation: HRANDFIELD</a>
|
||||
*/
|
||||
@Nullable
|
||||
byte[] hRandField(byte[] key);
|
||||
|
||||
/**
|
||||
* Return a random field from the hash value stored at {@code key}.
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @return {@literal null} if key does not exist or when used in pipeline / transaction.
|
||||
* @since 2.6
|
||||
* @see <a href="https://redis.io/commands/hrandfield">Redis Documentation: HRANDFIELD</a>
|
||||
*/
|
||||
@Nullable
|
||||
Map.Entry<byte[], byte[]> hRandFieldWithValues(byte[] key);
|
||||
|
||||
/**
|
||||
* Return a random field from the hash value stored at {@code key}. If the provided {@code count} argument is
|
||||
* positive, return a list of distinct fields, capped either at {@code count} or the hash size. If {@code count} is
|
||||
* negative, the behavior changes and the command is allowed to return the same field multiple times. In this case,
|
||||
* the number of returned fields is the absolute value of the specified count.
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @param count number of fields to return.
|
||||
* @return {@literal null} if key does not exist or when used in pipeline / transaction.
|
||||
* @since 2.6
|
||||
* @see <a href="https://redis.io/commands/hrandfield">Redis Documentation: HRANDFIELD</a>
|
||||
*/
|
||||
@Nullable
|
||||
List<byte[]> hRandField(byte[] key, long count);
|
||||
|
||||
/**
|
||||
* Return a random field from the hash value stored at {@code key}. If the provided {@code count} argument is
|
||||
* positive, return a list of distinct fields, capped either at {@code count} or the hash size. If {@code count} is
|
||||
* negative, the behavior changes and the command is allowed to return the same field multiple times. In this case,
|
||||
* the number of returned fields is the absolute value of the specified count.
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @param count number of fields to return.
|
||||
* @return {@literal null} if key does not exist or when used in pipeline / transaction.
|
||||
* @since 2.6
|
||||
* @see <a href="https://redis.io/commands/hrandfield">Redis Documentation: HRANDFIELD</a>
|
||||
*/
|
||||
@Nullable
|
||||
List<Map.Entry<byte[], byte[]>> hRandFieldWithValues(byte[] key, long count);
|
||||
|
||||
/**
|
||||
* Use a {@link Cursor} to iterate over entries in hash at {@code key}.
|
||||
*
|
||||
|
||||
@@ -1964,6 +1964,58 @@ public interface StringRedisConnection extends RedisConnection {
|
||||
*/
|
||||
Double hIncrBy(String key, String field, double delta);
|
||||
|
||||
/**
|
||||
* Return a random field from the hash value stored at {@code key}.
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @return {@literal null} if key does not exist or when used in pipeline / transaction.
|
||||
* @since 2.6
|
||||
* @see <a href="https://redis.io/commands/hrandfield">Redis Documentation: HRANDFIELD</a>
|
||||
*/
|
||||
@Nullable
|
||||
String hRandField(String key);
|
||||
|
||||
/**
|
||||
* Return a random field from the hash value stored at {@code key}.
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @return {@literal null} if key does not exist or when used in pipeline / transaction.
|
||||
* @since 2.6
|
||||
* @see <a href="https://redis.io/commands/hrandfield">Redis Documentation: HRANDFIELD</a>
|
||||
*/
|
||||
@Nullable
|
||||
Map.Entry<String, String> hRandFieldWithValues(String key);
|
||||
|
||||
/**
|
||||
* Return a random field from the hash value stored at {@code key}. If the provided {@code count} argument is
|
||||
* positive, return a list of distinct fields, capped either at {@code count} or the hash size. If {@code count} is
|
||||
* negative, the behavior changes and the command is allowed to return the same field multiple times. In this case,
|
||||
* the number of returned fields is the absolute value of the specified count.
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @param count number of fields to return.
|
||||
* @return {@literal null} if key does not exist or when used in pipeline / transaction.
|
||||
* @since 2.6
|
||||
* @see <a href="https://redis.io/commands/hrandfield">Redis Documentation: HRANDFIELD</a>
|
||||
*/
|
||||
@Nullable
|
||||
List<String> hRandField(String key, long count);
|
||||
|
||||
/**
|
||||
* Return a random field from the hash value stored at {@code key}. If the provided {@code count} argument is
|
||||
* positive, return a list of distinct fields, capped either at {@code count} or the hash size. If {@code count} is
|
||||
* negative, the behavior changes and the command is allowed to return the same field multiple times. In this case,
|
||||
* the number of returned fields is the absolute value of the specified count.
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @param count number of fields to return.
|
||||
* @return {@literal null} if key does not exist or when used in pipeline / transaction.
|
||||
* @since 2.6
|
||||
* @see <a href="https://redis.io/commands/hrandfield">Redis Documentation: HRANDFIELD</a>
|
||||
*/
|
||||
@Nullable
|
||||
List<Map.Entry<String, String>> hRandFieldWithValues(String key, long count);
|
||||
|
||||
/**
|
||||
* Determine if given hash {@code field} exists.
|
||||
*
|
||||
|
||||
@@ -461,6 +461,20 @@ abstract public class Converters {
|
||||
return source;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an {@link Map.Entry} from {@code key} and {@code value}.
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
* @param <K>
|
||||
* @param <V>
|
||||
* @return
|
||||
* @since 2.6
|
||||
*/
|
||||
public static <K, V> Map.Entry<K, V> entryOf(K key, V value) {
|
||||
return new SimpleEntry<>(key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
* @since 1.8
|
||||
@@ -639,4 +653,30 @@ abstract public class Converters {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class SimpleEntry<K, V> implements Map.Entry<K, V> {
|
||||
|
||||
private final K key;
|
||||
private final V value;
|
||||
|
||||
public SimpleEntry(K key, V value) {
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public K getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public V getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public V setValue(V value) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import org.springframework.data.redis.core.Cursor;
|
||||
import org.springframework.data.redis.core.ScanCursor;
|
||||
import org.springframework.data.redis.core.ScanIteration;
|
||||
import org.springframework.data.redis.core.ScanOptions;
|
||||
import org.springframework.data.util.Streamable;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -167,6 +168,74 @@ class JedisClusterHashCommands implements RedisHashCommands {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.RedisHashCommands#hRandField(byte[])
|
||||
*/
|
||||
@Nullable
|
||||
@Override
|
||||
public byte[] hRandField(byte[] key) {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
return connection.getCluster().hrandfield(key);
|
||||
} catch (Exception ex) {
|
||||
throw convertJedisAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.RedisHashCommands#hRandFieldWithValues(byte[])
|
||||
*/
|
||||
@Nullable
|
||||
@Override
|
||||
public Entry<byte[], byte[]> hRandFieldWithValues(byte[] key) {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
Map<byte[], byte[]> map = connection.getCluster().hrandfieldWithValues(key, 1);
|
||||
return map.isEmpty() ? null : map.entrySet().iterator().next();
|
||||
} catch (Exception ex) {
|
||||
throw convertJedisAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.RedisHashCommands#hRandField(byte[], long)
|
||||
*/
|
||||
@Nullable
|
||||
@Override
|
||||
public List<byte[]> hRandField(byte[] key, long count) {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
return connection.getCluster().hrandfield(key, count);
|
||||
} catch (Exception ex) {
|
||||
throw convertJedisAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.RedisHashCommands#hRandFieldWithValues(byte[], long)
|
||||
*/
|
||||
@Nullable
|
||||
@Override
|
||||
public List<Entry<byte[], byte[]>> hRandFieldWithValues(byte[] key, long count) {
|
||||
|
||||
try {
|
||||
Map<byte[], byte[]> map = connection.getCluster().hrandfieldWithValues(key, count);
|
||||
return Streamable.of(() -> map.entrySet().iterator()).toList();
|
||||
} catch (Exception ex) {
|
||||
throw convertJedisAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.RedisHashCommands#hExists(byte[], byte[])
|
||||
|
||||
@@ -20,12 +20,14 @@ import redis.clients.jedis.MultiKeyPipelineBase;
|
||||
import redis.clients.jedis.ScanParams;
|
||||
import redis.clients.jedis.ScanResult;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.data.redis.connection.RedisHashCommands;
|
||||
import org.springframework.data.redis.connection.convert.Converters;
|
||||
import org.springframework.data.redis.core.Cursor;
|
||||
import org.springframework.data.redis.core.KeyBoundCursor;
|
||||
import org.springframework.data.redis.core.ScanIteration;
|
||||
@@ -127,6 +129,67 @@ class JedisHashCommands implements RedisHashCommands {
|
||||
return connection.invoke().just(BinaryJedis::hgetAll, MultiKeyPipelineBase::hgetAll, key);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.RedisHashCommands#hRandField(byte[])
|
||||
*/
|
||||
@Nullable
|
||||
@Override
|
||||
public byte[] hRandField(byte[] key) {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
return connection.invoke().just(BinaryJedis::hrandfield, MultiKeyPipelineBase::hrandfield, key);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.RedisHashCommands#hRandFieldWithValues(byte[])
|
||||
*/
|
||||
@Nullable
|
||||
@Override
|
||||
public Entry<byte[], byte[]> hRandFieldWithValues(byte[] key) {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
return connection.invoke()
|
||||
.from(BinaryJedis::hrandfieldWithValues, MultiKeyPipelineBase::hrandfieldWithValues, key, 1L)
|
||||
.get(it -> it.isEmpty() ? null : it.entrySet().iterator().next());
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.RedisHashCommands#hRandField(byte[], long)
|
||||
*/
|
||||
@Nullable
|
||||
@Override
|
||||
public List<byte[]> hRandField(byte[] key, long count) {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
return connection.invoke().just(BinaryJedis::hrandfield, MultiKeyPipelineBase::hrandfield, key, count);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.RedisHashCommands#hRandFieldWithValues(byte[], long)
|
||||
*/
|
||||
@Nullable
|
||||
@Override
|
||||
public List<Entry<byte[], byte[]>> hRandFieldWithValues(byte[] key, long count) {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
return connection.invoke()
|
||||
.from(BinaryJedis::hrandfieldWithValues, MultiKeyPipelineBase::hrandfieldWithValues, key, count).get(it -> {
|
||||
|
||||
List<Entry<byte[], byte[]>> entries = new ArrayList<>(it.size());
|
||||
it.forEach((k, v) -> entries.add(Converters.entryOf(k, v)));
|
||||
|
||||
return entries;
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.RedisHashCommands#hIncrBy(byte[], byte[], long)
|
||||
@@ -280,4 +343,5 @@ class JedisHashCommands implements RedisHashCommands {
|
||||
private boolean isQueueing() {
|
||||
return connection.isQueueing();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.springframework.data.redis.connection.lettuce;
|
||||
|
||||
import io.lettuce.core.KeyValue;
|
||||
import io.lettuce.core.MapScanCursor;
|
||||
import io.lettuce.core.ScanArgs;
|
||||
import io.lettuce.core.api.async.RedisHashAsyncCommands;
|
||||
@@ -25,6 +26,7 @@ import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.data.redis.connection.RedisHashCommands;
|
||||
import org.springframework.data.redis.connection.convert.Converters;
|
||||
import org.springframework.data.redis.core.Cursor;
|
||||
import org.springframework.data.redis.core.KeyBoundCursor;
|
||||
import org.springframework.data.redis.core.ScanIteration;
|
||||
@@ -124,6 +126,60 @@ class LettuceHashCommands implements RedisHashCommands {
|
||||
return connection.invoke().just(RedisHashAsyncCommands::hgetall, key);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.RedisHashCommands#hRandField(byte[])
|
||||
*/
|
||||
@Nullable
|
||||
@Override
|
||||
public byte[] hRandField(byte[] key) {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
return connection.invoke().just(RedisHashAsyncCommands::hrandfield, key);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.RedisHashCommands#hRandFieldWithValues(byte[])
|
||||
*/
|
||||
@Nullable
|
||||
@Override
|
||||
public Entry<byte[], byte[]> hRandFieldWithValues(byte[] key) {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
return connection.invoke().from(RedisHashAsyncCommands::hrandfieldWithvalues, key)
|
||||
.get(LettuceHashCommands::toEntry);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.RedisHashCommands#hRandField(byte[], long)
|
||||
*/
|
||||
@Nullable
|
||||
@Override
|
||||
public List<byte[]> hRandField(byte[] key, long count) {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
return connection.invoke().just(RedisHashAsyncCommands::hrandfield, key, count);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.RedisHashCommands#hRandFieldWithValues(byte[], long)
|
||||
*/
|
||||
@Nullable
|
||||
@Override
|
||||
public List<Entry<byte[], byte[]>> hRandFieldWithValues(byte[] key, long count) {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
return connection.invoke().fromMany(RedisHashAsyncCommands::hrandfieldWithvalues, key, count)
|
||||
.toList(LettuceHashCommands::toEntry);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.RedisHashCommands#hIncrBy(byte[], byte[], long)
|
||||
@@ -275,4 +331,9 @@ class LettuceHashCommands implements RedisHashCommands {
|
||||
return connection.invoke().just(RedisHashAsyncCommands::hstrlen, key, field);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Entry<byte[], byte[]> toEntry(KeyValue<byte[], byte[]> value) {
|
||||
return value.hasValue() ? Converters.entryOf(value.getKey(), value.getValue()) : null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ import org.springframework.data.redis.connection.ReactiveRedisConnection.KeyComm
|
||||
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.convert.Converters;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -164,6 +165,39 @@ class LettuceReactiveHashCommands implements ReactiveHashCommands {
|
||||
}));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<CommandResponse<HRandFieldCommand, Flux<ByteBuffer>>> hRandField(Publisher<HRandFieldCommand> commands) {
|
||||
|
||||
return connection.execute(cmd -> Flux.from(commands).map(command -> {
|
||||
|
||||
Assert.notNull(command.getKey(), "Command.getKey() must not be null!");
|
||||
|
||||
return new CommandResponse<>(command, cmd.hrandfield(command.getKey(), command.getCount()));
|
||||
}));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<CommandResponse<HRandFieldCommand, Flux<Entry<ByteBuffer, ByteBuffer>>>> hRandFieldWithValues(
|
||||
Publisher<HRandFieldCommand> commands) {
|
||||
|
||||
return connection.execute(cmd -> Flux.from(commands).map(command -> {
|
||||
|
||||
Assert.notNull(command.getKey(), "Command.getKey() must not be null!");
|
||||
|
||||
Flux<Entry<ByteBuffer, ByteBuffer>> flux = cmd.hrandfieldWithvalues(command.getKey(), command.getCount())
|
||||
.handle((it, sink) -> {
|
||||
|
||||
if (it.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
sink.next(Converters.entryOf(it.getKey(), it.getValue()));
|
||||
});
|
||||
|
||||
return new CommandResponse<>(command, flux);
|
||||
}));
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.ReactiveHashCommands#hKeys(org.reactivestreams.Publisher)
|
||||
|
||||
@@ -282,6 +282,14 @@ abstract class AbstractOperations<K, V> {
|
||||
return SerializationUtils.deserialize(rawKeys, hashKeySerializer());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
<T> List<T> deserializeHashKeys(List<byte[]> rawKeys) {
|
||||
if (hashKeySerializer() == null) {
|
||||
return (List<T>) rawKeys;
|
||||
}
|
||||
return SerializationUtils.deserialize(rawKeys, hashKeySerializer());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
<T> List<T> deserializeHashValues(List<byte[]> rawValues) {
|
||||
if (hashValueSerializer() == null) {
|
||||
|
||||
@@ -88,6 +88,51 @@ public interface BoundHashOperations<H, HK, HV> extends BoundKeyOperations<H> {
|
||||
@Nullable
|
||||
Double increment(HK key, double delta);
|
||||
|
||||
/**
|
||||
* Return a random field from the hash value stored at the bound key.
|
||||
*
|
||||
* @return {@literal null} if key does not exist or when used in pipeline / transaction.
|
||||
* @since 2.6
|
||||
* @see <a href="https://redis.io/commands/hrandfield">Redis Documentation: HRANDFIELD</a>
|
||||
*/
|
||||
@Nullable
|
||||
HK randomField();
|
||||
|
||||
/**
|
||||
* Return a random field from the hash value stored at the bound key.
|
||||
*
|
||||
* @return {@literal null} if key does not exist or when used in pipeline / transaction.
|
||||
* @since 2.6
|
||||
* @see <a href="https://redis.io/commands/hrandfield">Redis Documentation: HRANDFIELD</a>
|
||||
*/
|
||||
@Nullable
|
||||
Map.Entry<HK, HV> randomValue();
|
||||
|
||||
/**
|
||||
* Return a random field from the hash value stored at the bound key. If the provided {@code count} argument is
|
||||
* positive, return a list of distinct fields, capped either at {@code count} or the hash size. If {@code count} is
|
||||
* negative, the behavior changes and the command is allowed to return the same field multiple times. In this case,
|
||||
* the number of returned fields is the absolute value of the specified count.
|
||||
*
|
||||
* @param count number of fields to return.
|
||||
* @return {@literal null} if key does not exist or when used in pipeline / transaction.
|
||||
* @since 2.6
|
||||
* @see <a href="https://redis.io/commands/hrandfield">Redis Documentation: HRANDFIELD</a>
|
||||
*/
|
||||
@Nullable
|
||||
List<HK> randomFields(long count);
|
||||
|
||||
/**
|
||||
* Return a random field from the hash value stored at the bound key.
|
||||
*
|
||||
* @param count number of fields to return. Must be positive.
|
||||
* @return {@literal null} if key does not exist or when used in pipeline / transaction.
|
||||
* @since 2.6
|
||||
* @see <a href="https://redis.io/commands/hrandfield">Redis Documentation: HRANDFIELD</a>
|
||||
*/
|
||||
@Nullable
|
||||
Map<HK, HV> randomValues(long count);
|
||||
|
||||
/**
|
||||
* Get key set (fields) of hash at the bound key.
|
||||
*
|
||||
|
||||
@@ -110,6 +110,46 @@ class DefaultBoundHashOperations<H, HK, HV> extends DefaultBoundKeyOperations<H>
|
||||
return ops.increment(getKey(), key, delta);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.core.BoundHashOperations#randomField()
|
||||
*/
|
||||
@Nullable
|
||||
@Override
|
||||
public HK randomField() {
|
||||
return ops.randomField(getKey());
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.core.BoundHashOperations#randomValue()
|
||||
*/
|
||||
@Nullable
|
||||
@Override
|
||||
public Entry<HK, HV> randomValue() {
|
||||
return ops.randomValue(getKey());
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.core.BoundHashOperations#randomFields(long)
|
||||
*/
|
||||
@Nullable
|
||||
@Override
|
||||
public List<HK> randomFields(long count) {
|
||||
return ops.randomFields(getKey(), count);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.core.BoundHashOperations#randomValues(long)
|
||||
*/
|
||||
@Nullable
|
||||
@Override
|
||||
public Map<HK, HV> randomValues(long count) {
|
||||
return ops.randomValues(getKey(), count);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.core.BoundHashOperations#keys()
|
||||
|
||||
@@ -24,7 +24,9 @@ import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.data.redis.connection.convert.Converters;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Default implementation of {@link HashOperations}.
|
||||
@@ -91,6 +93,67 @@ class DefaultHashOperations<K, HK, HV> extends AbstractOperations<K, Object> imp
|
||||
return execute(connection -> connection.hIncrBy(rawKey, rawHashKey, delta), true);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.core.HashOperations#randomField(java.lang.Object)
|
||||
*/
|
||||
@Nullable
|
||||
@Override
|
||||
public HK randomField(K key) {
|
||||
|
||||
byte[] rawKey = rawKey(key);
|
||||
return deserializeHashKey(execute(connection -> connection.hRandField(rawKey), true));
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.core.HashOperations#randomValue(java.lang.Object)
|
||||
*/
|
||||
@Nullable
|
||||
@Override
|
||||
public Entry<HK, HV> randomValue(K key) {
|
||||
|
||||
byte[] rawKey = rawKey(key);
|
||||
Entry<byte[], byte[]> rawEntry = execute(connection -> connection.hRandFieldWithValues(rawKey), true);
|
||||
return rawEntry == null ? null
|
||||
: Converters.entryOf(deserializeHashKey(rawEntry.getKey()), deserializeHashValue(rawEntry.getValue()));
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.core.HashOperations#randomFields(java.lang.Object, long)
|
||||
*/
|
||||
@Nullable
|
||||
@Override
|
||||
public List<HK> randomFields(K key, long count) {
|
||||
|
||||
byte[] rawKey = rawKey(key);
|
||||
List<byte[]> rawValues = execute(connection -> connection.hRandField(rawKey, count), true);
|
||||
return deserializeHashKeys(rawValues);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.core.HashOperations#randomValues(java.lang.Object, long)
|
||||
*/
|
||||
@Nullable
|
||||
@Override
|
||||
public Map<HK, HV> randomValues(K key, long count) {
|
||||
|
||||
Assert.isTrue(count > 0, "Count must not be negative");
|
||||
byte[] rawKey = rawKey(key);
|
||||
List<Entry<byte[], byte[]>> rawEntries = execute(connection -> connection.hRandFieldWithValues(rawKey, count),
|
||||
true);
|
||||
|
||||
if (rawEntries == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Map<byte[], byte[]> rawMap = new LinkedHashMap<>(rawEntries.size());
|
||||
rawEntries.forEach(entry -> rawMap.put(entry.getKey(), entry.getValue()));
|
||||
return deserializeHashMap(rawMap);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.core.HashOperations#keys(java.lang.Object)
|
||||
|
||||
@@ -144,6 +144,58 @@ class DefaultReactiveHashOperations<H, HK, HV> implements ReactiveHashOperations
|
||||
.hIncrBy(rawKey(key), rawHashKey(hashKey), delta));
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.core.ReactiveHashOperations#randomField(H)
|
||||
*/
|
||||
@Override
|
||||
public Mono<HK> randomField(H key) {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
return template.createMono(connection -> connection //
|
||||
.hashCommands().hRandField(rawKey(key))).map(this::readHashKey);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.core.ReactiveHashOperations#randomValue(H)
|
||||
*/
|
||||
@Override
|
||||
public Mono<Map.Entry<HK, HV>> randomValue(H key) {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
return template.createMono(connection -> connection //
|
||||
.hashCommands().hRandFieldWithValues(rawKey(key))).map(this::deserializeHashEntry);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.core.ReactiveHashOperations#randomFields(H, long)
|
||||
*/
|
||||
@Override
|
||||
public Flux<HK> randomFields(H key, long count) {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
return template.createFlux(connection -> connection //
|
||||
.hashCommands().hRandField(rawKey(key), count)).map(this::readHashKey);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.core.ReactiveHashOperations#randomValues(H, long)
|
||||
*/
|
||||
@Override
|
||||
public Flux<Map.Entry<HK, HV>> randomValues(H key, long count) {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
return template.createFlux(connection -> connection //
|
||||
.hashCommands().hRandFieldWithValues(rawKey(key), count)).map(this::deserializeHashEntry);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.core.ReactiveHashOperations#keys(java.lang.Object)
|
||||
|
||||
@@ -88,6 +88,55 @@ public interface HashOperations<H, HK, HV> {
|
||||
*/
|
||||
Double increment(H key, HK hashKey, double delta);
|
||||
|
||||
/**
|
||||
* Return a random field from the hash value stored at {@code key}.
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @return {@literal null} if key does not exist or when used in pipeline / transaction.
|
||||
* @since 2.6
|
||||
* @see <a href="https://redis.io/commands/hrandfield">Redis Documentation: HRANDFIELD</a>
|
||||
*/
|
||||
@Nullable
|
||||
HK randomField(H key);
|
||||
|
||||
/**
|
||||
* Return a random field from the hash value stored at {@code key}.
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @return {@literal null} if key does not exist or when used in pipeline / transaction.
|
||||
* @since 2.6
|
||||
* @see <a href="https://redis.io/commands/hrandfield">Redis Documentation: HRANDFIELD</a>
|
||||
*/
|
||||
@Nullable
|
||||
Map.Entry<HK, HV> randomValue(H key);
|
||||
|
||||
/**
|
||||
* Return a random field from the hash value stored at {@code key}. If the provided {@code count} argument is
|
||||
* positive, return a list of distinct fields, capped either at {@code count} or the hash size. If {@code count} is
|
||||
* negative, the behavior changes and the command is allowed to return the same field multiple times. In this case,
|
||||
* the number of returned fields is the absolute value of the specified count.
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @param count number of fields to return.
|
||||
* @return {@literal null} if key does not exist or when used in pipeline / transaction.
|
||||
* @since 2.6
|
||||
* @see <a href="https://redis.io/commands/hrandfield">Redis Documentation: HRANDFIELD</a>
|
||||
*/
|
||||
@Nullable
|
||||
List<HK> randomFields(H key, long count);
|
||||
|
||||
/**
|
||||
* Return a random field from the hash value stored at {@code key}.
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @param count number of fields to return. Must be positive.
|
||||
* @return {@literal null} if key does not exist or when used in pipeline / transaction.
|
||||
* @since 2.6
|
||||
* @see <a href="https://redis.io/commands/hrandfield">Redis Documentation: HRANDFIELD</a>
|
||||
*/
|
||||
@Nullable
|
||||
Map<HK, HV> randomValues(H key, long count);
|
||||
|
||||
/**
|
||||
* Get key set (fields) of hash at {@code key}.
|
||||
*
|
||||
|
||||
@@ -87,6 +87,54 @@ public interface ReactiveHashOperations<H, HK, HV> {
|
||||
*/
|
||||
Mono<Double> increment(H key, HK hashKey, double delta);
|
||||
|
||||
/**
|
||||
* Return a random field from the hash value stored at {@code key}.
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @return
|
||||
* @since 2.6
|
||||
* @see <a href="https://redis.io/commands/hrandfield">Redis Documentation: HRANDFIELD</a>
|
||||
*/
|
||||
Mono<HK> randomField(H key);
|
||||
|
||||
/**
|
||||
* Return a random field from the hash value stored at {@code key}.
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @return
|
||||
* @since 2.6
|
||||
* @see <a href="https://redis.io/commands/hrandfield">Redis Documentation: HRANDFIELD</a>
|
||||
*/
|
||||
Mono<Map.Entry<HK, HV>> randomValue(H key);
|
||||
|
||||
/**
|
||||
* Return a random field from the hash value stored at {@code key}. If the provided {@code count} argument is
|
||||
* positive, return a list of distinct fields, capped either at {@code count} or the hash size. If {@code count} is
|
||||
* negative, the behavior changes and the command is allowed to return the same field multiple times. In this case,
|
||||
* the number of returned fields is the absolute value of the specified count.
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @param count number of fields to return.
|
||||
* @return
|
||||
* @since 2.6
|
||||
* @see <a href="https://redis.io/commands/hrandfield">Redis Documentation: HRANDFIELD</a>
|
||||
*/
|
||||
Flux<HK> randomFields(H key, long count);
|
||||
|
||||
/**
|
||||
* Return a random field from the hash value stored at {@code key}. If the provided {@code count} argument is
|
||||
* positive, return a list of distinct fields, capped either at {@code count} or the hash size. If {@code count} is
|
||||
* negative, the behavior changes and the command is allowed to return the same field multiple times. In this case,
|
||||
* the number of returned fields is the absolute value of the specified count.
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @param count number of fields to return.
|
||||
* @return {@literal null} if key does not exist or when used in pipeline / transaction.
|
||||
* @since 2.6
|
||||
* @see <a href="https://redis.io/commands/hrandfield">Redis Documentation: HRANDFIELD</a>
|
||||
*/
|
||||
Flux<Map.Entry<HK, HV>> randomValues(H key, long count);
|
||||
|
||||
/**
|
||||
* Get key set (fields) of hash at {@code key}.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user