diff --git a/pom.xml b/pom.xml
index 8657b1992a..e6a3f337d5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
org.springframework.data
spring-data-redis
- 2.6.0-SNAPSHOT
+ 2.6.0-2037-SNAPSHOT
Spring Data Redis
diff --git a/src/main/asciidoc/new-features.adoc b/src/main/asciidoc/new-features.adoc
index 920916f201..5052a2be5a 100644
--- a/src/main/asciidoc/new-features.adoc
+++ b/src/main/asciidoc/new-features.adoc
@@ -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`, `ZPOPMIN`, `BZPOPMIN`, `ZPOPMAX`, `BZPOPMAX`, `ZMSCORE`, `ZDIFF`, `ZDIFFSTORE`, `ZINTER`, `ZUNION`).
+* Support Redis 6.2 commands (`LPOP`/`RPOP` with `count`, `COPY`, `GETEX`, `GETDEL`, `SMISMEMBER`, `ZPOPMIN`, `BZPOPMIN`, `ZPOPMAX`, `BZPOPMAX`, `ZMSCORE`, `ZDIFF`, `ZDIFFSTORE`, `ZINTER`, `ZUNION`).
[[new-in-2.5.0]]
== New in Spring Data Redis 2.5
diff --git a/src/main/java/org/springframework/data/redis/connection/DefaultStringRedisConnection.java b/src/main/java/org/springframework/data/redis/connection/DefaultStringRedisConnection.java
index 34222cb937..b3b16c43ca 100644
--- a/src/main/java/org/springframework/data/redis/connection/DefaultStringRedisConnection.java
+++ b/src/main/java/org/springframework/data/redis/connection/DefaultStringRedisConnection.java
@@ -1164,6 +1164,15 @@ public Boolean sIsMember(byte[] key, byte[] value) {
return convertAndReturn(delegate.sIsMember(key, value), Converters.identityConverter());
}
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.data.redis.connection.RedisSetCommands#sIsMember(byte[], byte[]...)
+ */
+ @Override
+ public List sMIsMember(byte[] key, byte[]... values) {
+ return convertAndReturn(delegate.sMIsMember(key, values), Converters.identityConverter());
+ }
+
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisSetCommands#sMembers(byte[])
@@ -2766,6 +2775,15 @@ public Boolean sIsMember(String key, String value) {
return sIsMember(serialize(key), serialize(value));
}
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.data.redis.connection.StringRedisConnection#sMIsMember(java.lang.String, java.lang.String...)
+ */
+ @Override
+ public List sMIsMember(String key, String... values) {
+ return sMIsMember(serialize(key), serializeMulti(values));
+ }
+
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.StringRedisConnection#sMembers(java.lang.String)
diff --git a/src/main/java/org/springframework/data/redis/connection/DefaultedRedisConnection.java b/src/main/java/org/springframework/data/redis/connection/DefaultedRedisConnection.java
index d7b2f346aa..ea16e5df17 100644
--- a/src/main/java/org/springframework/data/redis/connection/DefaultedRedisConnection.java
+++ b/src/main/java/org/springframework/data/redis/connection/DefaultedRedisConnection.java
@@ -835,6 +835,13 @@ default Boolean sIsMember(byte[] key, byte[] value) {
return setCommands().sIsMember(key, value);
}
+ /** @deprecated in favor of {@link RedisConnection#setCommands()}}. */
+ @Override
+ @Deprecated
+ default List sMIsMember(byte[] key, byte[]... value) {
+ return setCommands().sMIsMember(key, value);
+ }
+
/** @deprecated in favor of {@link RedisConnection#setCommands()}}. */
@Override
@Deprecated
diff --git a/src/main/java/org/springframework/data/redis/connection/ReactiveSetCommands.java b/src/main/java/org/springframework/data/redis/connection/ReactiveSetCommands.java
index 7da72e25aa..ee9adcfdc8 100644
--- a/src/main/java/org/springframework/data/redis/connection/ReactiveSetCommands.java
+++ b/src/main/java/org/springframework/data/redis/connection/ReactiveSetCommands.java
@@ -32,6 +32,7 @@
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.core.ScanOptions;
import org.springframework.lang.Nullable;
@@ -546,7 +547,7 @@ default Mono sIsMember(ByteBuffer key, ByteBuffer value) {
}
/**
- * Check if set at {@link SIsMemberCommand#getKey()} contains {@link SIsMemberCommand#getKey()}.
+ * Check if set at {@link SIsMemberCommand#getKey()} contains {@link SIsMemberCommand#getValue()}.
*
* @param commands must not be {@literal null}.
* @return
@@ -554,6 +555,86 @@ default Mono sIsMember(ByteBuffer key, ByteBuffer value) {
*/
Flux> sIsMember(Publisher commands);
+ /**
+ * {@code SMISMEMBER} command parameters.
+ *
+ * @author Mark Paluch
+ * @since 2.6
+ * @see Redis Documentation: SMISMEMBER
+ */
+ class SMIsMemberCommand extends KeyCommand {
+
+ private final List values;
+
+ private SMIsMemberCommand(@Nullable ByteBuffer key, List values) {
+
+ super(key);
+
+ this.values = values;
+ }
+
+ /**
+ * Creates a new {@link SMIsMemberCommand} given one or more {@literal values}.
+ *
+ * @param value must not be {@literal null}.
+ * @return a new {@link SMIsMemberCommand} for a {@literal value}.
+ */
+ public static SMIsMemberCommand values(List values) {
+
+ Assert.notNull(values, "Values must not be null!");
+ Assert.notEmpty(values, "Values must not be empty!");
+
+ return new SMIsMemberCommand(null, values);
+ }
+
+ /**
+ * Applies the {@literal set} key. Constructs a new command instance with all previously configured properties.
+ *
+ * @param set must not be {@literal null}.
+ * @return a new {@link SMIsMemberCommand} with {@literal set} applied.
+ */
+ public SMIsMemberCommand of(ByteBuffer set) {
+
+ Assert.notNull(set, "Set key must not be null!");
+
+ return new SMIsMemberCommand(set, values);
+ }
+
+ /**
+ * @return
+ */
+ public List getValues() {
+ return values;
+ }
+ }
+
+ /**
+ * Check if set at {@code key} contains one or more {@code values}.
+ *
+ * @param key must not be {@literal null}.
+ * @param values must not be {@literal null}.
+ * @return {@literal null} when used in pipeline / transaction.
+ * @since 2.6
+ * @see Redis Documentation: SMISMEMBER
+ */
+ default Mono> sMIsMember(ByteBuffer key, List values) {
+
+ Assert.notNull(key, "Key must not be null!");
+ Assert.notNull(values, "Value must not be null!");
+
+ return sMIsMember(Mono.just(SMIsMemberCommand.values(values).of(key))).next().map(MultiValueResponse::getOutput);
+ }
+
+ /**
+ * Check if set at {@link SMIsMemberCommand#getKey()} contains {@link SMIsMemberCommand#getValues()}.
+ *
+ * @param commands must not be {@literal null}.
+ * @return
+ * @since 2.6
+ * @see Redis Documentation: SMISMEMBER
+ */
+ Flux> sMIsMember(Publisher commands);
+
/**
* {@code SINTER} command parameters.
*
diff --git a/src/main/java/org/springframework/data/redis/connection/RedisSetCommands.java b/src/main/java/org/springframework/data/redis/connection/RedisSetCommands.java
index e9fb5765bb..5a03c0704a 100644
--- a/src/main/java/org/springframework/data/redis/connection/RedisSetCommands.java
+++ b/src/main/java/org/springframework/data/redis/connection/RedisSetCommands.java
@@ -108,6 +108,18 @@ public interface RedisSetCommands {
@Nullable
Boolean sIsMember(byte[] key, byte[] value);
+ /**
+ * Check if set at {@code key} contains one or more {@code values}.
+ *
+ * @param key must not be {@literal null}.
+ * @param values must not be {@literal null}.
+ * @return {@literal null} when used in pipeline / transaction.
+ * @since 2.6
+ * @see Redis Documentation: SMISMEMBER
+ */
+ @Nullable
+ List sMIsMember(byte[] key, byte[]... values);
+
/**
* Diff all sets for given {@code keys}.
*
diff --git a/src/main/java/org/springframework/data/redis/connection/StringRedisConnection.java b/src/main/java/org/springframework/data/redis/connection/StringRedisConnection.java
index 469aeed494..50ba6e7903 100644
--- a/src/main/java/org/springframework/data/redis/connection/StringRedisConnection.java
+++ b/src/main/java/org/springframework/data/redis/connection/StringRedisConnection.java
@@ -1043,6 +1043,19 @@ default Long lPos(String key, String element) {
*/
Boolean sIsMember(String key, String value);
+ /**
+ * Check if set at {@code key} contains one or more {@code values}.
+ *
+ * @param key must not be {@literal null}.
+ * @param values must not be {@literal null}.
+ * @return {@literal null} when used in pipeline / transaction.
+ * @since 2.6
+ * @see Redis Documentation: SMISMEMBER
+ * @see RedisSetCommands#sMIsMember(byte[], byte[]...)
+ */
+ @Nullable
+ List sMIsMember(String key, String... values);
+
/**
* Returns the members intersecting all given sets at {@code keys}.
*
diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterSetCommands.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterSetCommands.java
index 72bcb1e746..7031e39ad9 100644
--- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterSetCommands.java
+++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterSetCommands.java
@@ -177,6 +177,24 @@ public Boolean sIsMember(byte[] key, byte[] value) {
}
}
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.data.redis.connection.RedisSetCommands#sMIsMember(byte[], byte[]...)
+ */
+ @Override
+ public List sMIsMember(byte[] key, byte[]... values) {
+
+ Assert.notNull(key, "Key must not be null!");
+ Assert.notNull(values, "Value must not be null!");
+ Assert.noNullElements(values, "Values must not contain null elements!");
+
+ try {
+ return connection.getCluster().smismember(key, values);
+ } catch (Exception ex) {
+ throw convertJedisAccessException(ex);
+ }
+ }
+
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisSetCommands#sInter(byte[][])
diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisSetCommands.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisSetCommands.java
index 6f845145d0..5a33942403 100644
--- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisSetCommands.java
+++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisSetCommands.java
@@ -136,6 +136,20 @@ public Boolean sIsMember(byte[] key, byte[] value) {
return connection.invoke().just(BinaryJedis::sismember, MultiKeyPipelineBase::sismember, key, value);
}
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.data.redis.connection.RedisSetCommands#sMIsMember(byte[], byte[]...)
+ */
+ @Override
+ public List sMIsMember(byte[] key, byte[]... values) {
+
+ Assert.notNull(key, "Key must not be null!");
+ Assert.notNull(values, "Values must not be null!");
+ Assert.noNullElements(values, "Values must not contain null elements!");
+
+ return connection.invoke().just(BinaryJedis::smismember, MultiKeyPipelineBase::smismember, key, values);
+ }
+
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisSetCommands#sMembers(byte[])
diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveSetCommands.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveSetCommands.java
index 873193aa42..00bceee75a 100644
--- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveSetCommands.java
+++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveSetCommands.java
@@ -22,11 +22,13 @@
import java.nio.ByteBuffer;
import org.reactivestreams.Publisher;
+
import org.springframework.data.redis.connection.ReactiveRedisConnection.BooleanResponse;
import org.springframework.data.redis.connection.ReactiveRedisConnection.ByteBufferResponse;
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.ReactiveSetCommands;
import org.springframework.util.Assert;
@@ -163,6 +165,23 @@ public Flux> sIsMember(Publisher> sMIsMember(Publisher 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.smismember(command.getKey(), command.getValues().toArray(new ByteBuffer[0])).collectList()
+ .map(value -> new MultiValueResponse<>(command, value));
+ }));
+ }
+
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.ReactiveSetCommands#sInter(org.reactivestreams.Publisher)
diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceSetCommands.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceSetCommands.java
index 802288a022..68a3c5dc4f 100644
--- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceSetCommands.java
+++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceSetCommands.java
@@ -137,6 +137,20 @@ public Boolean sIsMember(byte[] key, byte[] value) {
return connection.invoke().just(RedisSetAsyncCommands::sismember, key, value);
}
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.data.redis.connection.RedisSetCommands#sMIsMember(byte[], byte[]...)
+ */
+ @Override
+ public List sMIsMember(byte[] key, byte[]... values) {
+
+ Assert.notNull(key, "Key must not be null!");
+ Assert.notNull(values, "Values must not be null!");
+ Assert.noNullElements(values, "Values must not contain null elements!");
+
+ return connection.invoke().just(RedisSetAsyncCommands::smismember, key, values);
+ }
+
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisSetCommands#sMembers(byte[])
diff --git a/src/main/java/org/springframework/data/redis/core/BoundSetOperations.java b/src/main/java/org/springframework/data/redis/core/BoundSetOperations.java
index 6d0a79ca9f..0ef9a697d6 100644
--- a/src/main/java/org/springframework/data/redis/core/BoundSetOperations.java
+++ b/src/main/java/org/springframework/data/redis/core/BoundSetOperations.java
@@ -17,6 +17,7 @@
import java.util.Collection;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import org.springframework.lang.Nullable;
@@ -88,6 +89,18 @@ public interface BoundSetOperations extends BoundKeyOperations {
@Nullable
Boolean isMember(Object o);
+ /**
+ * Check if set at at the bound key contains one or more {@code values}.
+ *
+ * @param key must not be {@literal null}.
+ * @param objects
+ * @return {@literal null} when used in pipeline / transaction.
+ * @since 2.6
+ * @see Redis Documentation: SMISMEMBER
+ */
+ @Nullable
+ Map