title: Redis sets

summary: Introduction to Redis sets

title: Set command summary

text:
**17 commands in this group:**

[View all set commands](https://redis.io/commands/?group=set)

| Command | Summary | Complexity | Since |
|---------|---------|------------|-------|
| [SADD](https://redis.io/commands/sadd/) | Adds one or more members to a set. Creates the key if it doesn't exist. | O(1) for each element added, so O(N) to add N e... | 1.0.0 |
| [SCARD](https://redis.io/commands/scard/) | Returns the number of members in a set. | O(1) | 1.0.0 |
| [SDIFF](https://redis.io/commands/sdiff/) | Returns the difference of multiple sets. | O(N) where N is the total number of elements in... | 1.0.0 |
| [SDIFFSTORE](https://redis.io/commands/sdiffstore/) | Stores the difference of multiple sets in a key. | O(N) where N is the total number of elements in... | 1.0.0 |
| [SINTER](https://redis.io/commands/sinter/) | Returns the intersect of multiple sets. | O(N*M) worst case where N is the cardinality of... | 1.0.0 |
| [SINTERCARD](https://redis.io/commands/sintercard/) | Returns the number of members of the intersect of multiple sets. | O(N*M) worst case where N is the cardinality of... | 7.0.0 |
| [SINTERSTORE](https://redis.io/commands/sinterstore/) | Stores the intersect of multiple sets in a key. | O(N*M) worst case where N is the cardinality of... | 1.0.0 |
| [SISMEMBER](https://redis.io/commands/sismember/) | Determines whether a member belongs to a set. | O(1) | 1.0.0 |
| [SMEMBERS](https://redis.io/commands/smembers/) | Returns all members of a set. | O(N) where N is the set cardinality. | 1.0.0 |
| [SMISMEMBER](https://redis.io/commands/smismember/) | Determines whether multiple members belong to a set. | O(N) where N is the number of elements being ch... | 6.2.0 |
| [SMOVE](https://redis.io/commands/smove/) | Moves a member from one set to another. | O(1) | 1.0.0 |
| [SPOP](https://redis.io/commands/spop/) | Returns one or more random members from a set after removing them. Deletes the set if the last member was popped. | Without the count argument O(1), otherwise O(N)... | 1.0.0 |
| [SRANDMEMBER](https://redis.io/commands/srandmember/) | Get one or multiple random members from a set | Without the count argument O(1), otherwise O(N)... | 1.0.0 |
| [SREM](https://redis.io/commands/srem/) | Removes one or more members from a set. Deletes the set if the last member was removed. | O(N) where N is the number of members to be rem... | 1.0.0 |
| [SSCAN](https://redis.io/commands/sscan/) | Iterates over members of a set. | O(1) for every call. O(N) for a complete iterat... | 2.8.0 |
| [SUNION](https://redis.io/commands/sunion/) | Returns the union of multiple sets. | O(N) where N is the total number of elements in... | 1.0.0 |
| [SUNIONSTORE](https://redis.io/commands/sunionstore/) | Stores the union of multiple sets in a key. | O(N) where N is the total number of elements in... | 1.0.0 |

A Redis set is an unordered collection of unique strings (members).
You can use Redis sets to efficiently:

* Track unique items (e.g., track all unique IP addresses accessing a given blog post).
* Represent relations (e.g., the set of all users with a given role).
* Perform common set operations such as intersection, unions, and differences.

title: Examples

text:
* Store the sets of bikes racing in France and the USA. Note that
if you add a member that already exists, it will be ignored.
#### Code Examples

Foundational: Add members to a set using SADD when you need to store unique items (duplicates are silently ignored)

**Difficulty:** Beginner

**Commands:** SADD

**Complexity:**
- SADD: O(1)

**Redis CLI:**

[code example]

**Available in:** Redis CLI, C# (Synchronous), Go, Java (Asynchronous - Lettuce), Java (Reactive - Lettuce), Java (Synchronous - Jedis), JavaScript (Node.js), PHP, Python

**C# (Synchronous):**

[code example]

**Go:**

[code example]

**Java (Asynchronous - Lettuce):**

[code example]

**Java (Reactive - Lettuce):**

[code example]

**Java (Synchronous - Jedis):**

[code example]

**JavaScript (Node.js):**

[code example]

**PHP:**

[code example]

**Python:**

[code example]

* Check whether bike:1 or bike:2 are racing in the US.
#### Code Examples

Foundational: Test set membership using SISMEMBER when you need O(1) lookups (much faster than checking a list)

**Difficulty:** Beginner

**Builds upon:** sadd

**Commands:** SISMEMBER

**Complexity:**
- SISMEMBER: O(1)

**Redis CLI:**

[code example]

**Available in:** Redis CLI, C# (Synchronous), Go, Java (Asynchronous - Lettuce), Java (Reactive - Lettuce), Java (Synchronous - Jedis), JavaScript (Node.js), PHP, Python

**C# (Synchronous):**

[code example]

**Go:**

[code example]

**Java (Asynchronous - Lettuce):**

[code example]

**Java (Reactive - Lettuce):**

[code example]

**Java (Synchronous - Jedis):**

[code example]

**JavaScript (Node.js):**

[code example]

**PHP:**

[code example]

**Python:**

[code example]

* Which bikes are competing in both races?
#### Code Examples

Set intersection: Find common members across multiple sets using SINTER when you need to identify shared items (e.g., users in multiple groups)

**Difficulty:** Intermediate

**Builds upon:** sadd

**Commands:** SINTER

**Complexity:**
- SINTER: O(N*M)

**Redis CLI:**

[code example]

**Available in:** Redis CLI, C# (Synchronous), Go, Java (Asynchronous - Lettuce), Java (Reactive - Lettuce), Java (Synchronous - Jedis), JavaScript (Node.js), PHP, Python

**C# (Synchronous):**

[code example]

**Go:**

[code example]

**Java (Asynchronous - Lettuce):**

[code example]

**Java (Reactive - Lettuce):**

[code example]

**Java (Synchronous - Jedis):**

[code example]

**JavaScript (Node.js):**

[code example]

**PHP:**

[code example]

**Python:**

[code example]

* How many bikes are racing in France?
#### Code Examples

Foundational: Get the cardinality of a set using SCARD when you need to count unique items efficiently

**Difficulty:** Beginner

**Builds upon:** sadd

**Commands:** SCARD

**Complexity:**
- SCARD: O(1)

**Redis CLI:**

[code example]

**Available in:** Redis CLI, C# (Synchronous), Go, Java (Asynchronous - Lettuce), Java (Reactive - Lettuce), Java (Synchronous - Jedis), JavaScript (Node.js), PHP, Python

**C# (Synchronous):**

[code example]

**Go:**

[code example]

**Java (Asynchronous - Lettuce):**

[code example]

**Java (Reactive - Lettuce):**

[code example]

**Java (Synchronous - Jedis):**

[code example]

**JavaScript (Node.js):**

[code example]

**PHP:**

[code example]

**Python:**

[code example]

title: Tutorial

text:
The [`SADD`]() command adds new elements to a set. It's also possible
to do a number of other operations against sets like testing if a given element
already exists, performing the intersection, union or difference between
multiple sets, and so forth.

#### Code Examples

Foundational: Retrieve all members from a set using SMEMBERS when you need the complete set (note: order is not guaranteed)

**Difficulty:** Beginner

**Builds upon:** sadd

**Commands:** DEL, SADD, SMEMBERS

**Complexity:**
- DEL: O(N)
- SADD: O(1)
- SMEMBERS: O(N)

**Redis CLI:**

[code example]

**Available in:** Redis CLI, C# (Synchronous), Go, Java (Asynchronous - Lettuce), Java (Reactive - Lettuce), Java (Synchronous - Jedis), JavaScript (Node.js), PHP, Python

**C# (Synchronous):**

[code example]

**Go:**

[code example]

**Java (Asynchronous - Lettuce):**

[code example]

**Java (Reactive - Lettuce):**

[code example]

**Java (Synchronous - Jedis):**

[code example]

**JavaScript (Node.js):**

[code example]

**PHP:**

[code example]

**Python:**

[code example]

Here I've added three elements to my set and told Redis to return all the
elements. There is no order guarantee with a set. Redis is free to return the
elements in any order at every call.

Redis has commands to test for set membership. These commands can be used on single as well as multiple items:

#### Code Examples

Batch membership checks: Test multiple items at once using SMISMEMBER when you need to reduce round trips to the server

**Difficulty:** Intermediate

**Builds upon:** sismember

**Commands:** SISMEMBER, SMISMEMBER

**Complexity:**
- SISMEMBER: O(1)
- SMISMEMBER: O(N)

**Redis CLI:**

[code example]

**Available in:** Redis CLI, C# (Synchronous), Go, Java (Asynchronous - Lettuce), Java (Reactive - Lettuce), Java (Synchronous - Jedis), JavaScript (Node.js), PHP, Python

**C# (Synchronous):**

[code example]

**Go:**

[code example]

**Java (Asynchronous - Lettuce):**

[code example]

**Java (Reactive - Lettuce):**

[code example]

**Java (Synchronous - Jedis):**

[code example]

**JavaScript (Node.js):**

[code example]

**PHP:**

[code example]

**Python:**

[code example]

We can also find the difference between two sets. For instance, we may want
to know which bikes are racing in France but not in the USA:

#### Code Examples

Set difference: Find members in one set but not in others using SDIFF when you need to exclude items (warning: argument order matters)

**Difficulty:** Intermediate

**Builds upon:** sadd

**Commands:** SADD, SDIFF

**Complexity:**
- SADD: O(1)
- SDIFF: O(N)

**Redis CLI:**

[code example]

**Available in:** Redis CLI, C# (Synchronous), Go, Java (Asynchronous - Lettuce), Java (Reactive - Lettuce), Java (Synchronous - Jedis), JavaScript (Node.js), PHP, Python

**C# (Synchronous):**

[code example]

**Go:**

[code example]

**Java (Asynchronous - Lettuce):**

[code example]

**Java (Reactive - Lettuce):**

[code example]

**Java (Synchronous - Jedis):**

[code example]

**JavaScript (Node.js):**

[code example]

**PHP:**

[code example]

**Python:**

[code example]

There are other non trivial operations that are still easy to implement
using the right Redis commands. For instance we may want a list of all the
bikes racing in France, the USA, and some other races. We can do this using
the [`SINTER`]() command, which performs the intersection between different
sets. In addition to intersection you can also perform
unions, difference, and more. For example
if we add a third race we can see some of these commands in action:

#### Code Examples

Advanced pattern: Combine SINTER, SUNION, and SDIFF to analyze complex relationships when you need to precompute set algebra across multiple datasets

**Difficulty:** Advanced

**Builds upon:** sinter, sdiff

**Commands:** DEL, SADD, SINTER, SUNION, SDIFF

**Complexity:**
- DEL: O(N)
- SADD: O(1)
- SINTER: O(N*M)
- SUNION: O(N)
- SDIFF: O(N)

**Redis CLI:**

[code example]

**Available in:** Redis CLI, C# (Synchronous), Go, Java (Asynchronous - Lettuce), Java (Reactive - Lettuce), Java (Synchronous - Jedis), JavaScript (Node.js), PHP, Python

**C# (Synchronous):**

[code example]

**Go:**

[code example]

**Java (Asynchronous - Lettuce):**

[code example]

**Java (Reactive - Lettuce):**

[code example]

**Java (Synchronous - Jedis):**

[code example]

**JavaScript (Node.js):**

[code example]

**PHP:**

[code example]

**Python:**

[code example]

You'll note that the [`SDIFF`]() command returns an empty array when the
difference between all sets is empty. You'll also note that the order of sets
passed to [`SDIFF`]() matters, since the difference is not commutative.

When you want to remove items from a set, you can use the [`SREM`]() command to
remove one or more items from a set, or you can use the [`SPOP`]() command to
remove a random item from a set. You can also _return_ a random item from a
set without removing it using the [`SRANDMEMBER`]() command:

#### Code Examples

Removal strategies: Use SREM for targeted removal, SPOP for random removal, or SRANDMEMBER to inspect without modifying when you need flexible deletion patterns

**Difficulty:** Intermediate

**Builds upon:** sadd

**Commands:** DEL, SADD, SREM, SPOP, SMEMBERS, SRANDMEMBER

**Complexity:**
- DEL: O(N)
- SADD: O(1)
- SREM: O(N)
- SMEMBERS: O(N)

**Redis CLI:**

[code example]

**Available in:** Redis CLI, C# (Synchronous), Go, Java (Asynchronous - Lettuce), Java (Reactive - Lettuce), Java (Synchronous - Jedis), JavaScript (Node.js), PHP, Python

**C# (Synchronous):**

[code example]

**Go:**

[code example]

**Java (Asynchronous - Lettuce):**

[code example]

**Java (Reactive - Lettuce):**

[code example]

**Java (Synchronous - Jedis):**

[code example]

**JavaScript (Node.js):**

[code example]

**PHP:**

[code example]

**Python:**

[code example]

title: Limits

text: The max size of a Redis set is 2^32 - 1 (4,294,967,295) members.

title: Performance

text:
Most set operations, including adding, removing, and checking whether an item is a set member, are O(1).
This means that they're highly efficient.
However, for large sets with hundreds of thousands of members or more, you should exercise caution when running the [`SMEMBERS`]() command.
This command is O(n) and returns the entire set in a single response.
As an alternative, consider the [`SSCAN`](), which lets you retrieve all members of a set iteratively.

title: Alternatives

text:
Sets membership checks on large datasets (or on streaming data) can use a lot of memory.
If you're concerned about memory usage and don't need perfect precision, consider a [Bloom filter or Cuckoo filter]() as an alternative to a set.

Redis sets are frequently used as a kind of index.
If you need to index and query your data, consider the [JSON]() data type and the [Redis Search]() features.

title: Learn more

text:
* [Redis Sets Explained](https://www.youtube.com/watch?v=PKdCppSNTGQ) and [Redis Sets Elaborated](https://www.youtube.com/watch?v=aRw5ME_5kMY) are two short but thorough video explainers covering Redis sets.
* [Redis University's RU101](https://university.redis.com/courses/ru101/) explores Redis sets in detail.

code:
> SADD bikes:racing:france bike:1
(integer) 1
> SADD bikes:racing:france bike:1
(integer) 0
> SADD bikes:racing:france bike:2 bike:3
(integer) 2
> SADD bikes:racing:usa bike:1 bike:4
(integer) 2

code:
long res1 = db.SetAdd("bikes:racing:france", ["bike:1"]);
        Console.WriteLine(res1);    // >>> 1

        long res2 = db.SetAdd("bikes:racing:france", ["bike:1"]);
        Console.WriteLine(res2);    // >>> 0

        long res3 = db.SetAdd("bikes:racing:france", ["bike:2", "bike:3"]);
        Console.WriteLine(res3);    // >>> 2

        long res4 = db.SetAdd("bikes:racing:usa", ["bike:1", "bike:4"]);
        Console.WriteLine(res4);    // >>> 2

code:
res1, err := rdb.SAdd(ctx, "bikes:racing:france", "bike:1").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res1) // >>> 1

	res2, err := rdb.SAdd(ctx, "bikes:racing:france", "bike:1").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res2) // >>> 0

	res3, err := rdb.SAdd(ctx, "bikes:racing:france", "bike:2", "bike:3").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res3) // >>> 2

	res4, err := rdb.SAdd(ctx, "bikes:racing:usa", "bike:1", "bike:4").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res4) // >>> 2

code:
CompletableFuture<Void> sAdd = asyncCommands.sadd("bikes:racing:france", "bike:1").thenCompose(res1 -> {
                System.out.println(res1); // >>> 1

                return asyncCommands.sadd("bikes:racing:france", "bike:1");
            }).thenCompose(res2 -> {
                System.out.println(res2); // >>> 0

                return asyncCommands.sadd("bikes:racing:france", "bike:2", "bike:3");
            }).thenCompose(res3 -> {
                System.out.println(res3); // >>> 2

                return asyncCommands.sadd("bikes:racing:usa", "bike:1", "bike:4");
            })
                    .thenAccept(System.out::println)
                    // >>> 2
                    .toCompletableFuture();

code:
Mono<Void> sAdd = reactiveCommands.sadd("bikes:racing:france", "bike:1").doOnNext(result -> {
                System.out.println(result); // >>> 1
            }).flatMap(v -> reactiveCommands.sadd("bikes:racing:france", "bike:1")).doOnNext(result -> {
                System.out.println(result); // >>> 0
            }).flatMap(v -> reactiveCommands.sadd("bikes:racing:france", "bike:2", "bike:3")).doOnNext(result -> {
                System.out.println(result); // >>> 2
            }).flatMap(v -> reactiveCommands.sadd("bikes:racing:usa", "bike:1", "bike:4")).doOnNext(result -> {
                System.out.println(result); // >>> 2
            }).then();

code:
long res1 = jedis.sadd("bikes:racing:france", "bike:1");
        System.out.println(res1);  // >>> 1

        long res2 = jedis.sadd("bikes:racing:france", "bike:1");
        System.out.println(res2);  // >>> 0

        long res3 = jedis.sadd("bikes:racing:france", "bike:2", "bike:3");
        System.out.println(res3);  // >>> 2

        long res4 = jedis.sadd("bikes:racing:usa", "bike:1", "bike:4");
        System.out.println(res4);  // >>> 2

code:
$res1 = $r->sadd('bikes:racing:france', ['bike:1']);
        echo $res1 . PHP_EOL;
        // >>> 1

        $res2 = $r->sadd('bikes:racing:france', ['bike:1']);
        echo $res2 . PHP_EOL;
        // >>> 0

        $res3 = $r->sadd('bikes:racing:france', ['bike:2', 'bike:3']);
        echo $res3 . PHP_EOL;
        // >>> 2

        $res4 = $r->sadd('bikes:racing:usa', ['bike:1', 'bike:4']);
        echo $res4 . PHP_EOL;
        // >>> 2

code:
res1 = r.sadd("bikes:racing:france", "bike:1")
print(res1)  # >>> 1

res2 = r.sadd("bikes:racing:france", "bike:1")
print(res2)  # >>> 0

res3 = r.sadd("bikes:racing:france", "bike:2", "bike:3")
print(res3)  # >>> 2

res4 = r.sadd("bikes:racing:usa", "bike:1", "bike:4")
print(res4)  # >>> 2

code:
> SISMEMBER bikes:racing:usa bike:1
(integer) 1
> SISMEMBER bikes:racing:usa bike:2
(integer) 0

code:
bool res5 = db.SetContains("bikes:racing:france", "bike:1");
        Console.WriteLine(res5);    // >>> True

        bool res6 = db.SetContains("bikes:racing:usa", "bike:2");
        Console.WriteLine(res6);    // >>> False

code:
res5, err := rdb.SIsMember(ctx, "bikes:racing:usa", "bike:1").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res5) // >>> true

	res6, err := rdb.SIsMember(ctx, "bikes:racing:usa", "bike:2").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res6) // >>> false

code:
CompletableFuture<Void> sIsMember = sAdd.thenCompose(r -> {
                return asyncCommands.sismember("bikes:racing:usa", "bike:1");
            }).thenCompose(res4 -> {
                System.out.println(res4); // >>> true

                return asyncCommands.sismember("bikes:racing:usa", "bike:2");
            })
                    .thenAccept(System.out::println) // >>> false
                    .toCompletableFuture();

code:
Mono<Boolean> sIsMember1 = reactiveCommands.sismember("bikes:racing:usa", "bike:1").doOnNext(result -> {
                System.out.println(result); // >>> true
            });

            Mono<Boolean> sIsMember2 = reactiveCommands.sismember("bikes:racing:usa", "bike:2").doOnNext(result -> {
                System.out.println(result); // >>> false
            });

code:
jedis.sadd("bikes:racing:france", "bike:1", "bike:2", "bike:3");
        jedis.sadd("bikes:racing:usa", "bike:1", "bike:4");

        boolean res5 = jedis.sismember("bikes:racing:usa", "bike:1");
        System.out.println(res5);  // >>> true

        boolean res6 = jedis.sismember("bikes:racing:usa", "bike:2");
        System.out.println(res6);  // >>> false

code:
$res5 = $r->sismember('bikes:racing:usa', 'bike:1');
        echo $res5 . PHP_EOL;
        // >>> 1

        $res6 = $r->sismember('bikes:racing:usa', 'bike:2');
        echo $res6 . PHP_EOL;
        // >>> 0

code:
r.sadd("bikes:racing:france", "bike:1", "bike:2", "bike:3")
r.sadd("bikes:racing:usa", "bike:1", "bike:4")
res5 = r.sismember("bikes:racing:usa", "bike:1")
print(res5)  # >>> 1

res6 = r.sismember("bikes:racing:usa", "bike:2")
print(res6)  # >>> 0

code:
> SINTER bikes:racing:france bikes:racing:usa
1) "bike:1"

code:
long res7 = db.SetAdd("{bikes:racing}:france", ["bike:1", "bike:2", "bike:3"]);
        long res8 = db.SetAdd("{bikes:racing}:usa", ["bike:1", "bike:4"]);

        RedisValue[] res9 = db.SetCombine(SetOperation.Intersect, ["{bikes:racing}:france", "{bikes:racing}:usa"]);
        Console.WriteLine(string.Join(", ", res9)); // >>> bike:1

code:
res7, err := rdb.SInter(ctx, "bikes:racing:france", "bikes:racing:usa").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res7) // >>> [bike:1]

code:
CompletableFuture<Void> sInter = sIsMember.thenCompose(r -> {
                return asyncCommands.sinter("bikes:racing:france", "bikes:racing:usa");
            })
                    .thenAccept(System.out::println) // >>> ["bike:1"]
                    .toCompletableFuture();

code:
Mono<List<String>> sInter = reactiveCommands.sinter("bikes:racing:france", "bikes:racing:usa").collectList()
                    .doOnNext(result -> {
                        System.out.println(result); // >>> [bike:1]
                    });

code:
jedis.sadd("bikes:racing:france", "bike:1", "bike:2", "bike:3");
        jedis.sadd("bikes:racing:usa", "bike:1", "bike:4");

        Set<String> res7 = jedis.sinter("bikes:racing:france", "bikes:racing:usa");
        System.out.println(res7);  // >>> [bike:1]

code:
import { createClient } from 'redis';

const client = createClient();
await client.connect();

const res1 = await client.sAdd('bikes:racing:france', 'bike:1')
console.log(res1)  // >>> 1

const res2 = await client.sAdd('bikes:racing:france', 'bike:1')
console.log(res2)  // >>> 0
const res3 = await client.sAdd('bikes:racing:france', ['bike:2', 'bike:3'])
console.log(res3)  // >>> 2
const res4 = await client.sAdd('bikes:racing:usa', ['bike:1', 'bike:4'])
console.log(res4)  // >>> 2

await client.del('bikes:racing:france')
await client.del('bikes:racing:usa')
await client.sAdd('bikes:racing:france', ['bike:1', 'bike:2', 'bike:3'])
await client.sAdd('bikes:racing:usa', ['bike:1', 'bike:4'])
const res5 = await client.sIsMember('bikes:racing:usa', 'bike:1')
console.log(res5)  // >>> 1

const res6 = await client.sIsMember('bikes:racing:usa', 'bike:2')
console.log(res6)  // >>> 0

await client.del('bikes:racing:france')
await client.del('bikes:racing:usa')
await client.sAdd('bikes:racing:france', ['bike:1', 'bike:2', 'bike:3'])
await client.sAdd('bikes:racing:usa', ['bike:1', 'bike:4'])
const res7 = await client.sInter(['bikes:racing:france', 'bikes:racing:usa'])
console.log(res7)  // >>> {'bike:1'}

await client.del('bikes:racing:france')
await client.sAdd('bikes:racing:france', ['bike:1', 'bike:2', 'bike:3'])
const res8 = await client.sCard('bikes:racing:france')
console.log(res8)  // >>> 3

await client.del('bikes:racing:france')

const res9 = await client.sAdd('bikes:racing:france', ['bike:1', 'bike:2', 'bike:3'])
console.log(res9)  // >>> 3

const res10 = await client.sMembers('bikes:racing:france')
console.log(res10)  // >>> ['bike:1', 'bike:2', 'bike:3']

const res11 = await client.sIsMember('bikes:racing:france', 'bike:1')
console.log(res11)  // >>> 1

const res12 = await client.smIsMember('bikes:racing:france', ['bike:2', 'bike:3', 'bike:4'])
console.log(res12)  // >>> [1, 1, 0]

await client.del('bikes:racing:france')
await client.del('bikes:racing:usa')

await client.sAdd('bikes:racing:france', ['bike:1', 'bike:2', 'bike:3'])
await client.sAdd('bikes:racing:usa', ['bike:1', 'bike:4'])
const res13 = await client.sDiff(['bikes:racing:france', 'bikes:racing:usa'])
console.log(res13)  // >>> [ 'bike:2', 'bike:3' ]

await client.del('bikes:racing:france')
await client.del('bikes:racing:usa')
await client.del('bikes:racing:italy')

await client.sAdd('bikes:racing:france', ['bike:1', 'bike:2', 'bike:3'])
await client.sAdd('bikes:racing:usa', ['bike:1', 'bike:4'])
await client.sAdd('bikes:racing:italy', ['bike:1', 'bike:2', 'bike:3', 'bike:4'])

const res14 = await client.sInter(
  ['bikes:racing:france', 'bikes:racing:usa', 'bikes:racing:italy']
)
console.log(res14)  // >>> ['bike:1']

const res15 = await client.sUnion(
  ['bikes:racing:france', 'bikes:racing:usa', 'bikes:racing:italy']
)
console.log(res15)  // >>> ['bike:1', 'bike:2', 'bike:3', 'bike:4']

const res16 = await client.sDiff(['bikes:racing:france', 'bikes:racing:usa', 'bikes:racing:italy'])
console.log(res16)  // >>> []

const res17 = await client.sDiff(['bikes:racing:usa', 'bikes:racing:france'])
console.log(res17)  // >>> ['bike:4']

const res18 = await client.sDiff(['bikes:racing:france', 'bikes:racing:usa'])
console.log(res18)  // >>> ['bike:2', 'bike:3']

await client.del('bikes:racing:france')

await client.sAdd('bikes:racing:france', ['bike:1', 'bike:2', 'bike:3', 'bike:4', 'bike:5'])

const res19 = await client.sRem('bikes:racing:france', 'bike:1')
console.log(res19)  // >>> 1

const res20 = await client.sPop('bikes:racing:france')
console.log(res20)  // >>> bike:3 or other random value

const res21 = await client.sMembers('bikes:racing:france')
console.log(res21)  // >>> ['bike:2', 'bike:4', 'bike:5']; depends on previous result

const res22 = await client.sRandMember('bikes:racing:france')
console.log(res22)  // >>> bike:4 or other random value

code:
$res7 = $r->sinter(['bikes:racing:france', 'bikes:racing:usa']);
        echo json_encode($res7) . PHP_EOL;
        // >>> ["bike:1"]

code:
r.sadd("bikes:racing:france", "bike:1", "bike:2", "bike:3")
r.sadd("bikes:racing:usa", "bike:1", "bike:4")
res7 = r.sinter("bikes:racing:france", "bikes:racing:usa")
print(res7)  # >>> {'bike:1'}

code:
> SCARD bikes:racing:france
(integer) 3

code:
long res10 = db.SetAdd("bikes:racing:france", ["bike:1", "bike:2", "bike:3"]);
        long res11 = db.SetLength("bikes:racing:france");
        Console.WriteLine(res11);   // >>> 3

code:
res8, err := rdb.SCard(ctx, "bikes:racing:france").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res8) // >>> 3

code:
CompletableFuture<Void> sCard = sInter.thenCompose(r -> {
                return asyncCommands.scard("bikes:racing:france");
            })
                    .thenAccept(System.out::println) // >>> 3
                    .toCompletableFuture();

code:
Mono<Long> sCard = reactiveCommands.scard("bikes:racing:france").doOnNext(result -> {
                System.out.println(result); // >>> 3
            });

code:
jedis.sadd("bikes:racing:france", "bike:1", "bike:2", "bike:3");

        long res8 = jedis.scard("bikes:racing:france");
        System.out.println(res8);  // >>> 3

code:
await client.del('bikes:racing:france')
await client.sAdd('bikes:racing:france', ['bike:1', 'bike:2', 'bike:3'])
const res8 = await client.sCard('bikes:racing:france')
console.log(res8)  // >>> 3

code:
$res8 = $r->scard('bikes:racing:france');
        echo $res8 . PHP_EOL;
        // >>> 3

code:
r.sadd("bikes:racing:france", "bike:1", "bike:2", "bike:3")
res8 = r.scard("bikes:racing:france")
print(res8)  # >>> 3

code:
> DEL bikes:racing:france
(integer) 1
> SADD bikes:racing:france bike:1 bike:2 bike:3
(integer) 3
> SMEMBERS bikes:racing:france
1) bike:3
2) bike:1
3) bike:2

section_id: tutorial

code:
db.KeyDelete("bikes:racing:france");

        long res12 = db.SetAdd("bikes:racing:france", ["bike:1", "bike:2", "bike:3"]);
        RedisValue[] res13 = db.SetMembers("bikes:racing:france");
        Console.WriteLine(string.Join(", ", res13));    // >>> bike:3, bike:2, bike:1

code:
rdb.Del(ctx, "bikes:racing:france")

	res9, err := rdb.SAdd(ctx, "bikes:racing:france", "bike:1", "bike:2", "bike:3").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res9) // >>> 3

	res10, err := rdb.SMembers(ctx, "bikes:racing:france").Result()

	if err != nil {
		panic(err)
	}

	// Sort the strings in the slice to make sure the output is lexicographical
	sort.Strings(res10)

	fmt.Println(res10) // >>> [bike:1 bike:2 bike:3]

code:
CompletableFuture<Void> sAddSMembers = sCard.thenCompose(r -> {
                return asyncCommands.del("bikes:racing:france");
            }).thenCompose(r -> {
                return asyncCommands.sadd("bikes:racing:france", "bike:1", "bike:2", "bike:3");
            }).thenCompose(res5 -> {
                System.out.println(res5); // >>> 3
                return asyncCommands.smembers("bikes:racing:france");
            })
                    .thenAccept(System.out::println)
                    // >>> [bike:1, bike:2, bike:3]
                    .toCompletableFuture();

code:
Mono<Void> sAddSMembers = reactiveCommands.sadd("bikes:racing:france", "bike:1", "bike:2", "bike:3")
                    .doOnNext(result -> {
                        System.out.println(result); // >>> 3
                    }).flatMap(v -> reactiveCommands.smembers("bikes:racing:france").collectList()).doOnNext(result -> {
                        System.out.println(result); // >>> [bike:1, bike:2, bike:3]
                    }).then();

code:
jedis.del("bikes:racing:france");

        long res9 = jedis.sadd("bikes:racing:france", "bike:1", "bike:2", "bike:3");
        System.out.println(res9);  // >>> 3

        Set<String> res10 = jedis.smembers("bikes:racing:france");
        System.out.println(res10);  // >>> [bike:1, bike:2, bike:3]

code:
$r->del('bikes:racing:france');

        $res9 = $r->sadd('bikes:racing:france', ['bike:1', 'bike:2', 'bike:3']);
        echo $res9 . PHP_EOL;
        // >>> 3

        $res10 = $r->smembers('bikes:racing:france');
        sort($res10);
        echo json_encode($res10) . PHP_EOL;
        // >>> ["bike:1","bike:2","bike:3"]

code:
r.delete("bikes:racing:france")

res9 = r.sadd("bikes:racing:france", "bike:1", "bike:2", "bike:3")
print(res9)  # >>> 3

res10 = r.smembers("bikes:racing:france")
print(res10)  # >>> {'bike:1', 'bike:2', 'bike:3'}

code:
> SISMEMBER bikes:racing:france bike:1
(integer) 1
> SMISMEMBER bikes:racing:france bike:2 bike:3 bike:4
1) (integer) 1
2) (integer) 1
3) (integer) 0

code:
bool res14 = db.SetContains("bikes:racing:france", "bike:1");
        Console.WriteLine(res14);   // >>> true

        bool[] res15 = db.SetContains("bikes:racing:france", ["bike:2", "bike:3", "bike:4"]);
        Console.WriteLine(string.Join(", ", res15));    // >>> True, True, False

code:
res11, err := rdb.SIsMember(ctx, "bikes:racing:france", "bike:1").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res11) // >>> true

	res12, err := rdb.SMIsMember(ctx, "bikes:racing:france", "bike:2", "bike:3", "bike:4").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res12) // >>> [true true false]

code:
CompletableFuture<Void> sMIsMember = sAddSMembers.thenCompose(r -> {
                return asyncCommands.sismember("bikes:racing:france", "bike:1");
            }).thenCompose(res6 -> {
                System.out.println(res6); // >>> True
                return asyncCommands.smismember("bikes:racing:france", "bike:2", "bike:3", "bike:4");
            })
                    .thenAccept(System.out::println) // >>> [true, true, false]
                    .toCompletableFuture();

code:
Mono<Boolean> sIsMember3 = reactiveCommands.sismember("bikes:racing:france", "bike:1").doOnNext(result -> {
                System.out.println(result); // >>> true
            });

            Mono<List<Boolean>> sMIsMember = reactiveCommands.smismember("bikes:racing:france", "bike:2", "bike:3", "bike:4")
                    .collectList().doOnNext(result -> {
                        System.out.println(result); // >>> [true, true, false]
                    });

code:
boolean res11 = jedis.sismember("bikes:racing:france", "bike:1");
        System.out.println(res11);  // >>> true

        List<Boolean> res12 = jedis.smismember("bikes:racing:france", "bike:2", "bike:3", "bike:4");
        System.out.println(res12);  // >>> [true,true,false]

code:
$res11 = $r->sismember('bikes:racing:france', 'bike:1');
        echo $res11 . PHP_EOL;
        // >>> 1

        $res12 = $r->smismember('bikes:racing:france', 'bike:2', 'bike:3', 'bike:4');
        echo json_encode($res12) . PHP_EOL;
        // >>> [1,1,0]

code:
res11 = r.sismember("bikes:racing:france", "bike:1")
print(res11)  # >>> 1

res12 = r.smismember("bikes:racing:france", "bike:2", "bike:3", "bike:4")
print(res12)  # >>> [1, 1, 0]

code:
> SADD bikes:racing:usa bike:1 bike:4
(integer) 2
> SDIFF bikes:racing:france bikes:racing:usa
1) "bike:3"
2) "bike:2"

code:
long res16 = db.SetAdd("{bikes:racing}:france", ["bike:1", "bike:2", "bike:3"]);
        long res17 = db.SetAdd("{bikes:racing}:usa", ["bike:1", "bike:4"]);
        RedisValue[] res18 = db.SetCombine(SetOperation.Difference, ["{bikes:racing}:france", "{bikes:racing}:usa"]);
        Console.WriteLine(string.Join(", ", res18));    // >>> bike:2, bike:3

code:
_, err := rdb.SAdd(ctx, "bikes:racing:france", "bike:1", "bike:2", "bike:3").Result()

	if err != nil {
		panic(err)
	}

	_, err = rdb.SAdd(ctx, "bikes:racing:usa", "bike:1", "bike:4").Result()

	res13, err := rdb.SDiff(ctx, "bikes:racing:france", "bikes:racing:usa").Result()

	if err != nil {
		panic(err)
	}

	// Sort the strings in the slice to make sure the output is lexicographical
	sort.Strings(res13)

	fmt.Println(res13) // >>> [bike:2 bike:3]

code:
CompletableFuture<Void> sDiff = sMIsMember.thenCompose(r -> {
                return asyncCommands.sadd("bikes:racing:france", "bike:1", "bike:2", "bike:3");
            }).thenCompose(r -> {
                return asyncCommands.sadd("bikes:racing:usa", "bike:1", "bike:4");
            }).thenCompose(r -> {
                return asyncCommands.sdiff("bikes:racing:france", "bikes:racing:usa");
            })
                    .thenAccept(System.out::println) // >>> [bike:2, bike:3]
                    .toCompletableFuture();

code:
Mono<List<String>> sDiff = reactiveCommands.sdiff("bikes:racing:france", "bikes:racing:usa").collectList()
                    .doOnNext(result -> {
                        System.out.println(result); // >>> [bike:2, bike:3]
                    });

code:
jedis.sadd("bikes:racing:france", "bike:1", "bike:2", "bike:3");
        jedis.sadd("bikes:racing:usa", "bike:1", "bike:4");

        Set<String> res13 = jedis.sdiff("bikes:racing:france", "bikes:racing:usa");
        System.out.println(res13);  // >>> [bike:2, bike:3]

code:
$r->sadd('bikes:racing:france', ['bike:1', 'bike:2', 'bike:3']);
        $r->sadd('bikes:racing:usa', ['bike:1', 'bike:4']);

        $res13 = $r->sdiff(['bikes:racing:france', 'bikes:racing:usa']);
        sort($res13);
        echo json_encode($res13) . PHP_EOL;
        // >>> ["bike:2","bike:3"]

code:
r.sadd("bikes:racing:france", "bike:1", "bike:2", "bike:3")
r.sadd("bikes:racing:usa", "bike:1", "bike:4")

res13 = r.sdiff("bikes:racing:france", "bikes:racing:usa")
print(res13)  # >>> {'bike:2', 'bike:3'}

code:
> DEL bikes:racing:france bikes:racing:usa bikes:racing:italy
(integer) 2
> SADD bikes:racing:france bike:1 bike:2 bike:3
(integer) 3
> SADD bikes:racing:usa bike:1 bike:4
(integer) 2
> SADD bikes:racing:italy bike:1 bike:2 bike:3 bike:4
(integer) 4
> SINTER bikes:racing:france bikes:racing:usa bikes:racing:italy
1) "bike:1"
> SUNION bikes:racing:france bikes:racing:usa bikes:racing:italy
1) "bike:2"
2) "bike:1"
3) "bike:4"
4) "bike:3"
> SDIFF bikes:racing:france bikes:racing:usa bikes:racing:italy
(empty array)
> SDIFF bikes:racing:france bikes:racing:usa
1) "bike:3"
2) "bike:2"
> SDIFF bikes:racing:usa bikes:racing:france
1) "bike:4"

code:
db.KeyDelete("{bikes:racing}:france");
        db.KeyDelete("{bikes:racing}:usa");
        db.KeyDelete("{bikes:racing}:italy");

        long res19 = db.SetAdd("{bikes:racing}:france", ["bike:1", "bike:2", "bike:3"]);
        long res20 = db.SetAdd("{bikes:racing}:usa", ["bike:1", "bike:4"]);
        long res21 = db.SetAdd("{bikes:racing}:italy", ["bike:1", "bike:2", "bike:3", "bike:4"]);

        RedisValue[] res22 = db.SetCombine(SetOperation.Intersect, ["{bikes:racing}:france", "{bikes:racing}:usa", "{bikes:racing}:italy"
        ]);
        Console.WriteLine(string.Join(", ", res22));    // >>> bike:1

        RedisValue[] res23 = db.SetCombine(SetOperation.Union, ["{bikes:racing}:france", "{bikes:racing}:usa", "{bikes:racing}:italy"
        ]);
        Console.WriteLine(string.Join(", ", res23));    // >>> bike:1, bike:2, bike:3, bike:4

        RedisValue[] res24 = db.SetCombine(SetOperation.Difference, ["{bikes:racing}:france", "{bikes:racing}:usa", "{bikes:racing}:italy"
        ]);
        Console.WriteLine(string.Join(", ", res24));    // >>> <empty set>

        RedisValue[] res25 = db.SetCombine(SetOperation.Difference, ["{bikes:racing}:usa", "{bikes:racing}:france"]);
        Console.WriteLine(string.Join(", ", res25));    // >>> bike:4

        RedisValue[] res26 = db.SetCombine(SetOperation.Difference, ["{bikes:racing}:france", "{bikes:racing}:usa"]);
        Console.WriteLine(string.Join(", ", res26));    // >>> bike:2, bike:3

code:
rdb.Del(ctx, "bikes:racing:france")
	rdb.Del(ctx, "bikes:racing:usa")
	rdb.Del(ctx, "bikes:racing:italy")

	_, err := rdb.SAdd(ctx, "bikes:racing:france", "bike:1", "bike:2", "bike:3").Result()

	if err != nil {
		panic(err)
	}

	_, err = rdb.SAdd(ctx, "bikes:racing:usa", "bike:1", "bike:4").Result()

	if err != nil {
		panic(err)
	}

	_, err = rdb.SAdd(ctx, "bikes:racing:italy", "bike:1", "bike:2", "bike:3", "bike:4").Result()

	if err != nil {
		panic(err)
	}

	res14, err := rdb.SInter(ctx, "bikes:racing:france", "bikes:racing:usa", "bikes:racing:italy").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res14) // >>> [bike:1]

	res15, err := rdb.SUnion(ctx, "bikes:racing:france", "bikes:racing:usa", "bikes:racing:italy").Result()

	if err != nil {
		panic(err)
	}

	// Sort the strings in the slice to make sure the output is lexicographical
	sort.Strings(res15)

	fmt.Println(res15) // >>> [bike:1 bike:2 bike:3 bike:4]

	res16, err := rdb.SDiff(ctx, "bikes:racing:france", "bikes:racing:usa", "bikes:racing:italy").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res16) // >>> []

	res17, err := rdb.SDiff(ctx, "bikes:racing:usa", "bikes:racing:france").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res17) // >>> [bike:4]

	res18, err := rdb.SDiff(ctx, "bikes:racing:france", "bikes:racing:usa").Result()

	if err != nil {
		panic(err)
	}

	// Sort the strings in the slice to make sure the output is lexicographical
	sort.Strings(res18)

	fmt.Println(res18) // >>> [bike:2 bike:3]

code:
CompletableFuture<Void> multisets = sDiff.thenCompose(r -> {
                return asyncCommands.sadd("bikes:racing:france", "bike:1", "bike:2", "bike:3");
            }).thenCompose(r -> {
                return asyncCommands.sadd("bikes:racing:usa", "bike:1", "bike:4");
            }).thenCompose(r -> {
                return asyncCommands.sadd("bikes:racing:italy", "bike:1", "bike:2", "bike:3", "bike:4");
            }).thenCompose(r -> {
                return asyncCommands.sinter("bikes:racing:france", "bikes:racing:usa", "bikes:racing:italy");
            }).thenCompose(res7 -> {
                System.out.println(res7); // >>> [bike:1]
                return asyncCommands.sunion("bikes:racing:france", "bikes:racing:usa", "bikes:racing:italy");
            }).thenCompose(res8 -> {
                System.out.println(res8);
                // >>> [bike:1, bike:2, bike:3, bike:4]
                return asyncCommands.sdiff("bikes:racing:france", "bikes:racing:usa", "bikes:racing:italy");
            }).thenCompose(res9 -> {
                System.out.println(res9); // >>> []
                return asyncCommands.sdiff("bikes:racing:usa", "bikes:racing:france");
            }).thenCompose(res10 -> {
                System.out.println(res10); // >>> [bike:4]
                return asyncCommands.sdiff("bikes:racing:france", "bikes:racing:usa");
            })
                    .thenAccept(System.out::println) // >>> [bike:2, bike:3]
                    .toCompletableFuture();

code:
Mono<Void> add3sets = reactiveCommands.sadd("bikes:racing:france", "bike:1", "bike:2", "bike:3")
                    .doOnNext(result -> {
                        System.out.println(result); // >>> 0
                    }).flatMap(v -> reactiveCommands.sadd("bikes:racing:usa", "bike:1", "bike:4")).doOnNext(result -> {
                        System.out.println(result); // >>> 0
                    }).flatMap(v -> reactiveCommands.sadd("bikes:racing:italy", "bike:1", "bike:2", "bike:3", "bike:4"))
                    .doOnNext(result -> {
                        System.out.println(result); // >>> 4,
                    }).then();
            add3sets.block();

            Mono<List<String>> multisets1 = reactiveCommands
                    .sinter("bikes:racing:france", "bikes:racing:usa", "bikes:racing:italy").collectList().doOnNext(result -> {
                        System.out.println(result); // >>> [bike:1]
                    });

            Mono<List<String>> multisets2 = reactiveCommands
                    .sunion("bikes:racing:france", "bikes:racing:usa", "bikes:racing:italy").collectList().doOnNext(result -> {
                        System.out.println(result); // >>> [bike:1, bike:2, bike:3, bike:4]
                    });

            Mono<List<String>> multisets3 = reactiveCommands
                    .sdiff("bikes:racing:france", "bikes:racing:usa", "bikes:racing:italy").collectList().doOnNext(result -> {
                        System.out.println(result); // >>> []
                    });

            Mono<List<String>> multisets4 = reactiveCommands.sdiff("bikes:racing:usa", "bikes:racing:france").collectList()
                    .doOnNext(result -> {
                        System.out.println(result); // >>> [bike:4]
                    });

            Mono<List<String>> multisets5 = reactiveCommands.sdiff("bikes:racing:france", "bikes:racing:usa").collectList()
                    .doOnNext(result -> {
                        System.out.println(result); // >>> [bike:2, bike:3]
                    });

code:
jedis.del("bikes:racing:france");
        jedis.del("bikes:racing:usa");
        jedis.del("bikes:racing:italy");

        jedis.sadd("bikes:racing:france", "bike:1", "bike:2", "bike:3");
        jedis.sadd("bikes:racing:usa", "bike:1", "bike:4");
        jedis.sadd("bikes:racing:italy", "bike:1", "bike:2", "bike:3", "bike:4");

        Set<String> res14 = jedis.sinter("bikes:racing:france", "bikes:racing:usa", "bikes:racing:italy");
        System.out.println(res14);  // >>> [bike:1]

        Set<String> res15 = jedis.sunion("bikes:racing:france", "bikes:racing:usa", "bikes:racing:italy");
        System.out.println(res15);  // >>> [bike:1, bike:2, bike:3, bike:4]

        Set<String> res16 = jedis.sdiff("bikes:racing:france", "bikes:racing:usa", "bikes:racing:italy");
        System.out.println(res16);  // >>> []

        Set<String> res17 = jedis.sdiff("bikes:racing:usa", "bikes:racing:france");
        System.out.println(res17);  // >>> [bike:4]

        Set<String> res18 = jedis.sdiff("bikes:racing:france", "bikes:racing:usa");
        System.out.println(res18);  // >>> [bike:2, bike:3]

code:
$r->del('bikes:racing:france');
        $r->del('bikes:racing:usa');
        $r->del('bikes:racing:italy');

        $r->sadd('bikes:racing:france', ['bike:1', 'bike:2', 'bike:3']);
        $r->sadd('bikes:racing:usa', ['bike:1', 'bike:4']);
        $r->sadd('bikes:racing:italy', ['bike:1', 'bike:2', 'bike:3', 'bike:4']);

        $res14 = $r->sinter(['bikes:racing:france', 'bikes:racing:usa', 'bikes:racing:italy']);
        echo json_encode($res14) . PHP_EOL;
        // >>> ["bike:1"]

        $res15 = $r->sunion(['bikes:racing:france', 'bikes:racing:usa', 'bikes:racing:italy']);
        sort($res15);
        echo json_encode($res15) . PHP_EOL;
        // >>> ["bike:1","bike:2","bike:3","bike:4"]

        $res16 = $r->sdiff(['bikes:racing:france', 'bikes:racing:usa', 'bikes:racing:italy']);
        echo json_encode($res16) . PHP_EOL;
        // >>> []

        $res17 = $r->sdiff(['bikes:racing:usa', 'bikes:racing:france']);
        echo json_encode($res17) . PHP_EOL;
        // >>> ["bike:4"]

        $res18 = $r->sdiff(['bikes:racing:france', 'bikes:racing:usa']);
        sort($res18);
        echo json_encode($res18) . PHP_EOL;
        // >>> ["bike:2","bike:3"]

code:
r.delete("bikes:racing:france")
r.delete("bikes:racing:usa")
r.delete("bikes:racing:italy")

r.sadd("bikes:racing:france", "bike:1", "bike:2", "bike:3")
r.sadd("bikes:racing:usa", "bike:1", "bike:4")
r.sadd("bikes:racing:italy", "bike:1", "bike:2", "bike:3", "bike:4")

res13 = r.sinter("bikes:racing:france", "bikes:racing:usa", "bikes:racing:italy")
print(res13)  # >>> {'bike:1'}

res14 = r.sunion("bikes:racing:france", "bikes:racing:usa", "bikes:racing:italy")
print(res14)  # >>> {'bike:1', 'bike:2', 'bike:3', 'bike:4'}

res15 = r.sdiff("bikes:racing:france", "bikes:racing:usa", "bikes:racing:italy")
print(res15)  # >>> set()

res16 = r.sdiff("bikes:racing:usa", "bikes:racing:france")
print(res16)  # >>> {'bike:4'}

res17 = r.sdiff("bikes:racing:france", "bikes:racing:usa")
print(res17)  # >>> {'bike:2', 'bike:3'}

code:
> DEL bikes:racing:france
(integer) 1
> SADD bikes:racing:france bike:1 bike:2 bike:3 bike:4 bike:5
(integer) 5
> SREM bikes:racing:france bike:1
(integer) 1
> SPOP bikes:racing:france
"bike:3"
> SMEMBERS bikes:racing:france
1) "bike:2"
2) "bike:4"
3) "bike:5"
> SRANDMEMBER bikes:racing:france
"bike:2"

code:
db.KeyDelete("bikes:racing:france");

        long res27 = db.SetAdd("bikes:racing:france", ["bike:1", "bike:2", "bike:3", "bike:4", "bike:5"]);

        bool res28 = db.SetRemove("bikes:racing:france", "bike:1");
        Console.WriteLine(res28);   // >>> True

        RedisValue res29 = db.SetPop("bikes:racing:france");
        Console.WriteLine(res29);   // >>> bike:3

        RedisValue[] res30 = db.SetMembers("bikes:racing:france");
        Console.WriteLine(string.Join(", ", res30));    // >>> bike:2, bike:4, bike:5

        RedisValue res31 = db.SetRandomMember("bikes:racing:france");
        Console.WriteLine(res31);   // >>> bike:4

code:
rdb.Del(ctx, "bikes:racing:france")

	_, err := rdb.SAdd(ctx, "bikes:racing:france", "bike:1", "bike:2", "bike:3", "bike:4", "bike:5").Result()

	if err != nil {
		panic(err)
	}

	res19, err := rdb.SRem(ctx, "bikes:racing:france", "bike:1").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res19) // >>> 1

	res20, err := rdb.SPop(ctx, "bikes:racing:france").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res20) // >>> <random element>

	res21, err := rdb.SMembers(ctx, "bikes:racing:france").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res21) // >>> <remaining elements>

	res22, err := rdb.SRandMember(ctx, "bikes:racing:france").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res22) // >>> <random element>

code:
CompletableFuture<Void> sRem = multisets.thenCompose(r -> {
                return asyncCommands.sadd("bikes:racing:france", "bike:1", "bike:2", "bike:3", "bike:4", "bike:5");
            }).thenCompose(r -> {
                return asyncCommands.srem("bikes:racing:france", "bike:1");
            }).thenCompose(res11 -> {
                System.out.println(res11); // >>> 1
                return asyncCommands.spop("bikes:racing:france");
            }).thenCompose(res12 -> {
                System.out.println(res12); // >>> bike:3 (for example)
                return asyncCommands.smembers("bikes:racing:france");
            }).thenCompose(res13 -> {
                System.out.println(res13); // >>> [bike:2, bike:4, bike:5]
                return asyncCommands.srandmember("bikes:racing:france");
            }).thenAccept(System.out::println) // >>> bike:4
                    .toCompletableFuture();

code:
Mono<Void> sRem = reactiveCommands.sadd("bikes:racing:france", "bike:1", "bike:2", "bike:3", "bike:4", "bike:5")
                    .doOnNext(result -> {
                        System.out.println(result); // >>> 2
                    }).flatMap(v -> reactiveCommands.srem("bikes:racing:france", "bike:1")).doOnNext(result -> {
                        System.out.println(result); // >>> 1
                    }).flatMap(v -> reactiveCommands.spop("bikes:racing:france")).doOnNext(result -> {
                        System.out.println(result); // >>> bike:3 (for example)
                    }).flatMap(v -> reactiveCommands.smembers("bikes:racing:france").collectList()).doOnNext(result -> {
                        System.out.println(result); // >>> [bike:2, bike:4, bike:5] (for example)
                    }).flatMap(v -> reactiveCommands.srandmember("bikes:racing:france")).doOnNext(result -> {
                        System.out.println(result); // >>> bike:4 (for example)
                    }).then();

code:
jedis.del("bikes:racing:france");
        jedis.sadd("bikes:racing:france", "bike:1", "bike:2", "bike:3", "bike:4", "bike:5");

        long res19 = jedis.srem("bikes:racing:france", "bike:1");
        System.out.println(res18);  // >>> 1

        String res20 = jedis.spop("bikes:racing:france");
        System.out.println(res20);  // >>> bike:3

        Set<String> res21 = jedis.smembers("bikes:racing:france");
        System.out.println(res21);  // >>> [bike:2, bike:4, bike:5]

        String res22 = jedis.srandmember("bikes:racing:france");
        System.out.println(res22);  // >>> bike:4

code:
$r->del('bikes:racing:france');

        $r->sadd('bikes:racing:france', ['bike:1', 'bike:2', 'bike:3', 'bike:4', 'bike:5']);

        $res19 = $r->srem('bikes:racing:france', ['bike:1']);
        echo $res19 . PHP_EOL;
        // >>> 1

        $res20 = $r->spop('bikes:racing:france');
        echo $res20 . PHP_EOL;
        // >>> bike:3 (for example)

        $res21 = $r->smembers('bikes:racing:france');
        sort($res21);
        echo json_encode($res21) . PHP_EOL;
        // >>> ["bike:2","bike:4","bike:5"]

        $res22 = $r->srandmember('bikes:racing:france');
        echo $res22 . PHP_EOL;
        // >>> bike:4 (for example)

code:
r.delete("bikes:racing:france")

r.sadd("bikes:racing:france", "bike:1", "bike:2", "bike:3", "bike:4", "bike:5")

res18 = r.srem("bikes:racing:france", "bike:1")
print(res18)  # >>> 1

res19 = r.spop("bikes:racing:france")
print(res19)  # >>> bike:3

res20 = r.smembers("bikes:racing:france")
print(res20)  # >>> {'bike:2', 'bike:4', 'bike:5'}

res21 = r.srandmember("bikes:racing:france")
print(res21)  # >>> bike:4


title: Redis sorted sets

summary: Introduction to Redis sorted sets

page_type: content

title: Sorted set command summary

role: content

text:
**35 commands in this group:**

[View all sorted-set commands](https://redis.io/commands/?group=sorted-set)

| Command | Summary | Complexity | Since |
|---------|---------|------------|-------|
| [BZMPOP](https://redis.io/commands/bzmpop/) | Removes and returns a member by score from one or more sorted sets. Blocks until a member is available otherwise. Deletes the sorted set if the last element was popped. | O(K) + O(M*log(N)) where K is the number of pro... | 7.0.0 |
| [BZPOPMAX](https://redis.io/commands/bzpopmax/) | Removes and returns the member with the highest score from one or more sorted sets. Blocks until a member available otherwise.  Deletes the sorted set if the last element was popped. | O(log(N)) with N being the number of elements i... | 5.0.0 |
| [BZPOPMIN](https://redis.io/commands/bzpopmin/) | Removes and returns the member with the lowest score from one or more sorted sets. Blocks until a member is available otherwise. Deletes the sorted set if the last element was popped. | O(log(N)) with N being the number of elements i... | 5.0.0 |
| [ZADD](https://redis.io/commands/zadd/) | Adds one or more members to a sorted set, or updates their scores. Creates the key if it doesn't exist. | O(log(N)) for each item added, where N is the n... | 1.2.0 |
| [ZCARD](https://redis.io/commands/zcard/) | Returns the number of members in a sorted set. | O(1) | 1.2.0 |
| [ZCOUNT](https://redis.io/commands/zcount/) | Returns the count of members in a sorted set that have scores within a range. | O(log(N)) with N being the number of elements i... | 2.0.0 |
| [ZDIFF](https://redis.io/commands/zdiff/) | Returns the difference between multiple sorted sets. | O(L + (N-K)log(N)) worst case where L is the to... | 6.2.0 |
| [ZDIFFSTORE](https://redis.io/commands/zdiffstore/) | Stores the difference of multiple sorted sets in a key. | O(L + (N-K)log(N)) worst case where L is the to... | 6.2.0 |
| [ZINCRBY](https://redis.io/commands/zincrby/) | Increments the score of a member in a sorted set. | O(log(N)) where N is the number of elements in ... | 1.2.0 |
| [ZINTER](https://redis.io/commands/zinter/) | Returns the intersect of multiple sorted sets. | O(N*K)+O(M*log(M)) worst case with N being the ... | 6.2.0 |
| [ZINTERCARD](https://redis.io/commands/zintercard/) | Returns the number of members of the intersect of multiple sorted sets. | O(N*K) worst case with N being the smallest inp... | 7.0.0 |
| [ZINTERSTORE](https://redis.io/commands/zinterstore/) | Stores the intersect of multiple sorted sets in a key. | O(N*K)+O(M*log(M)) worst case with N being the ... | 2.0.0 |
| [ZLEXCOUNT](https://redis.io/commands/zlexcount/) | Returns the number of members in a sorted set within a lexicographical range. | O(log(N)) with N being the number of elements i... | 2.8.9 |
| [ZMPOP](https://redis.io/commands/zmpop/) | Returns the highest- or lowest-scoring members from one or more sorted sets after removing them. Deletes the sorted set if the last member was popped. | O(K) + O(M*log(N)) where K is the number of pro... | 7.0.0 |
| [ZMSCORE](https://redis.io/commands/zmscore/) | Returns the score of one or more members in a sorted set. | O(N) where N is the number of members being req... | 6.2.0 |
| [ZPOPMAX](https://redis.io/commands/zpopmax/) | Returns the highest-scoring members from a sorted set after removing them. Deletes the sorted set if the last member was popped. | O(log(N)*M) with N being the number of elements... | 5.0.0 |
| [ZPOPMIN](https://redis.io/commands/zpopmin/) | Returns the lowest-scoring members from a sorted set after removing them. Deletes the sorted set if the last member was popped. | O(log(N)*M) with N being the number of elements... | 5.0.0 |
| [ZRANDMEMBER](https://redis.io/commands/zrandmember/) | Returns one or more random members from a sorted set. | O(N) where N is the number of members returned | 6.2.0 |
| [ZRANGE](https://redis.io/commands/zrange/) | Returns members in a sorted set within a range of indexes. | O(log(N)+M) with N being the number of elements... | 1.2.0 |
| [ZRANGEBYLEX](https://redis.io/commands/zrangebylex/) | Returns members in a sorted set within a lexicographical range. | O(log(N)+M) with N being the number of elements... | 2.8.9 |
| [ZRANGEBYSCORE](https://redis.io/commands/zrangebyscore/) | Returns members in a sorted set within a range of scores. | O(log(N)+M) with N being the number of elements... | 1.0.5 |
| [ZRANGESTORE](https://redis.io/commands/zrangestore/) | Stores a range of members from sorted set in a key. | O(log(N)+M) with N being the number of elements... | 6.2.0 |
| [ZRANK](https://redis.io/commands/zrank/) | Returns the index of a member in a sorted set ordered by ascending scores. | O(log(N)) | 2.0.0 |
| [ZREM](https://redis.io/commands/zrem/) | Removes one or more members from a sorted set. Deletes the sorted set if all members were removed. | O(M*log(N)) with N being the number of elements... | 1.2.0 |
| [ZREMRANGEBYLEX](https://redis.io/commands/zremrangebylex/) | Removes members in a sorted set within a lexicographical range. Deletes the sorted set if all members were removed. | O(log(N)+M) with N being the number of elements... | 2.8.9 |
| [ZREMRANGEBYRANK](https://redis.io/commands/zremrangebyrank/) | Removes members in a sorted set within a range of indexes. Deletes the sorted set if all members were removed. | O(log(N)+M) with N being the number of elements... | 2.0.0 |
| [ZREMRANGEBYSCORE](https://redis.io/commands/zremrangebyscore/) | Removes members in a sorted set within a range of scores. Deletes the sorted set if all members were removed. | O(log(N)+M) with N being the number of elements... | 1.2.0 |
| [ZREVRANGE](https://redis.io/commands/zrevrange/) | Returns members in a sorted set within a range of indexes in reverse order. | O(log(N)+M) with N being the number of elements... | 1.2.0 |
| [ZREVRANGEBYLEX](https://redis.io/commands/zrevrangebylex/) | Returns members in a sorted set within a lexicographical range in reverse order. | O(log(N)+M) with N being the number of elements... | 2.8.9 |
| [ZREVRANGEBYSCORE](https://redis.io/commands/zrevrangebyscore/) | Returns members in a sorted set within a range of scores in reverse order. | O(log(N)+M) with N being the number of elements... | 2.2.0 |
| [ZREVRANK](https://redis.io/commands/zrevrank/) | Returns the index of a member in a sorted set ordered by descending scores. | O(log(N)) | 2.0.0 |
| [ZSCAN](https://redis.io/commands/zscan/) | Iterates over members and scores of a sorted set. | O(1) for every call. O(N) for a complete iterat... | 2.8.0 |
| [ZSCORE](https://redis.io/commands/zscore/) | Returns the score of a member in a sorted set. | O(1) | 1.2.0 |
| [ZUNION](https://redis.io/commands/zunion/) | Returns the union of multiple sorted sets. | O(N)+O(M*log(M)) with N being the sum of the si... | 6.2.0 |
| [ZUNIONSTORE](https://redis.io/commands/zunionstore/) | Stores the union of multiple sorted sets in a key. | O(N)+O(M log(M)) with N being the sum of the si... | 2.0.0 |

A Redis sorted set is a collection of unique strings (members) ordered by an associated score.
When more than one string has the same score, the strings are ordered lexicographically.
Some use cases for sorted sets include:

* Leaderboards. For example, you can use sorted sets to easily maintain  ordered lists of the highest scores in a massive online game.
* Rate limiters. In particular, you can use a sorted set to build a sliding-window rate limiter to prevent excessive API requests.

You can think of sorted sets as a mix between a Set and
a Hash. Like sets, sorted sets are composed of unique, non-repeating
string elements, so in some sense a sorted set is a set as well.

However while elements inside sets are not ordered, every element in
a sorted set is associated with a floating point value, called *the score*
(this is why the type is also similar to a hash, since every element
is mapped to a value).

Moreover, elements in a sorted set are *taken in order* (so they are not
ordered on request, order is a peculiarity of the data structure used to
represent sorted sets). They are ordered according to the following rule:

* If B and A are two elements with a different score, then A > B if A.score is > B.score.
* If B and A have exactly the same score, then A > B if the A string is lexicographically greater than the B string. B and A strings can't be equal since sorted sets only have unique elements.

Let's start with a simple example, we'll add all our racers and the score they got in the first race:

#### Code Examples

Foundational: Add members to a sorted set with their scores (creates new members or updates existing ones)

**Commands:** ZADD

**Complexity:**
- ZADD: O(log(N)

**Redis CLI:**

[code example]

**Available in:** Redis CLI, C# (Synchronous), Go, Java (Asynchronous - Lettuce), Java (Synchronous - Jedis), JavaScript (Node.js), PHP, Python

**C# (Synchronous):**

[code example]

**Go:**

[code example]

**Java (Asynchronous - Lettuce):**

[code example]

**Java (Synchronous - Jedis):**

[code example]

**JavaScript (Node.js):**

[code example]

**PHP:**

[code example]

**Python:**

[code example]

As you can see [`ZADD`]() is similar to [`SADD`](), but takes one additional argument
(placed before the element to be added) which is the score.
[`ZADD`]() is also variadic, so you are free to specify multiple score-value
pairs, as shown in the example above.

With sorted sets it is trivial to return a list of racers sorted by their
score because actually *they are already sorted*.

Implementation note: Sorted sets are implemented via a
dual-ported data structure containing both a skip list and a hash table, so
every time we add an element Redis performs an O(log(N)) operation. That's
good, so when we ask for sorted elements, Redis does not have to do any work at
all, it's already sorted. Note that the [`ZRANGE`]() order is low to high, while the [`ZREVRANGE`]() order is high to low:

#### Code Examples

Retrieve members in ascending or descending order using ZRANGE and ZREVRANGE (no sorting needed, already ordered)

**Builds upon:** zadd

**Commands:** ZRANGE, ZREVRANGE

**Complexity:**
- ZRANGE: O(log(N)
- ZREVRANGE: O(log(N)

**Redis CLI:**

[code example]

**Available in:** Redis CLI, C# (Synchronous), Go, Java (Asynchronous - Lettuce), Java (Synchronous - Jedis), JavaScript (Node.js), PHP, Python

**C# (Synchronous):**

[code example]

**Go:**

[code example]

**Java (Asynchronous - Lettuce):**

[code example]

**Java (Synchronous - Jedis):**

[code example]

**JavaScript (Node.js):**

[code example]

**PHP:**

[code example]

**Python:**

[code example]

Note: 0 and -1 means from element index 0 to the last element (-1 works
here just as it does in the case of the [`LRANGE`]() command).

It is possible to return scores as well, using the `WITHSCORES` argument:

#### Code Examples

Retrieve members with their scores using WITHSCORES when you need both the member and its associated score value

**Builds upon:** zrange

**Commands:** ZRANGE

**Complexity:**
- ZRANGE: O(log(N)

**Redis CLI:**

[code example]

**Available in:** Redis CLI, C# (Synchronous), Go, Java (Asynchronous - Lettuce), Java (Synchronous - Jedis), JavaScript (Node.js), PHP, Python

**C# (Synchronous):**

[code example]

**Go:**

[code example]

**Java (Asynchronous - Lettuce):**

[code example]

**Java (Synchronous - Jedis):**

[code example]

**JavaScript (Node.js):**

[code example]

**PHP:**

[code example]

**Python:**

[code example]

title: Operating on ranges

text:
Sorted sets are more powerful than this. They can operate on ranges.
Let's get all the racers with 10 or fewer points. We
use the [`ZRANGEBYSCORE`]() command to do it:

#### Code Examples

Query by score range: Retrieve members within a score range using ZRANGEBYSCORE when you need to filter by numeric values

**Difficulty:** Intermediate

**Builds upon:** zadd

**Commands:** ZRANGEBYSCORE

**Complexity:**
- ZRANGEBYSCORE: O(log(N)

**Redis CLI:**

[code example]

**Available in:** Redis CLI, C# (Synchronous), Go, Java (Asynchronous - Lettuce), Java (Synchronous - Jedis), JavaScript (Node.js), PHP, Python

**C# (Synchronous):**

[code example]

**Go:**

[code example]

**Java (Asynchronous - Lettuce):**

[code example]

**Java (Synchronous - Jedis):**

[code example]

**JavaScript (Node.js):**

[code example]

**PHP:**

[code example]

**Python:**

[code example]

We asked Redis to return all the elements with a score between negative
infinity and 10 (both extremes are included).

To remove an element we'd simply call [`ZREM`]() with the racer's name.
It's also possible to remove ranges of elements. Let's remove racer Castilla along with all
the racers with strictly fewer than 10 points:

#### Code Examples

Remove members using ZREM for individual elements or ZREMRANGEBYSCORE for score ranges when you need to delete data

**Difficulty:** Intermediate

**Builds upon:** zadd

**Commands:** ZREM, ZREMRANGEBYSCORE, ZRANGE

**Complexity:**
- ZREM: O(M*log(N)
- ZREMRANGEBYSCORE: O(log(N)
- ZRANGE: O(log(N)

**Redis CLI:**

[code example]

**Available in:** Redis CLI, C# (Synchronous), Go, Java (Asynchronous - Lettuce), Java (Synchronous - Jedis), JavaScript (Node.js), PHP, Python

**C# (Synchronous):**

[code example]

**Go:**

[code example]

**Java (Asynchronous - Lettuce):**

[code example]

**Java (Synchronous - Jedis):**

[code example]

**JavaScript (Node.js):**

[code example]

**PHP:**

[code example]

**Python:**

[code example]

[`ZREMRANGEBYSCORE`]() is perhaps not the best command name,
but it can be very useful, and returns the number of removed elements.

Another extremely useful operation defined for sorted set elements
is the get-rank operation. It is possible to ask what is the
position of an element in the set of ordered elements.
The [`ZREVRANK`]() command is also available in order to get the rank, considering
the elements sorted in a descending way.

#### Code Examples

Get member position: Use ZRANK and ZREVRANK to find a member's position in the sorted set (useful for leaderboards)

**Difficulty:** Intermediate

**Builds upon:** zadd

**Commands:** ZRANK, ZREVRANK

**Complexity:**
- ZRANK: O(log(N)
- ZREVRANK: O(log(N)

**Redis CLI:**

[code example]

**Available in:** Redis CLI, C# (Synchronous), Go, Java (Asynchronous - Lettuce), Java (Synchronous - Jedis), JavaScript (Node.js), PHP, Python

**C# (Synchronous):**

[code example]

**Go:**

[code example]

**Java (Asynchronous - Lettuce):**

[code example]

**Java (Synchronous - Jedis):**

[code example]

**JavaScript (Node.js):**

[code example]

**PHP:**

[code example]

**Python:**

[code example]

title: Lexicographical scores

text:
In version Redis 2.8, a new feature was introduced that allows
getting ranges lexicographically, assuming elements in a sorted set are all
inserted with the same identical score (elements are compared with the C
`memcmp` function, so it is guaranteed that there is no collation, and every
Redis instance will reply with the same output).

The main commands to operate with lexicographical ranges are [`ZRANGEBYLEX`](),
[`ZREVRANGEBYLEX`](), [`ZREMRANGEBYLEX`]() and [`ZLEXCOUNT`]().

For example, let's add again our list of famous racers, but this time
using a score of zero for all the elements. We'll see that because of the sorted sets ordering rules, they are already sorted lexicographically. Using [`ZRANGEBYLEX`]() we can ask for lexicographical ranges:

#### Code Examples

Lexicographical queries: Add members with identical scores and use ZRANGEBYLEX to query by string range (enables generic indexing)

**Difficulty:** Intermediate

**Builds upon:** zadd

**Commands:** ZADD, ZRANGE, ZRANGEBYLEX

**Complexity:**
- ZADD: O(log(N)
- ZRANGE: O(log(N)
- ZRANGEBYLEX: O(log(N)

**Redis CLI:**

[code example]

**Available in:** Redis CLI, C# (Synchronous), Go, Java (Asynchronous - Lettuce), Java (Synchronous - Jedis), JavaScript (Node.js), PHP, Python

**C# (Synchronous):**

[code example]

**Go:**

[code example]

**Java (Asynchronous - Lettuce):**

[code example]

**Java (Synchronous - Jedis):**

[code example]

**JavaScript (Node.js):**

[code example]

**PHP:**

[code example]

**Python:**

[code example]

Ranges can be inclusive or exclusive (depending on the first character),
also string infinite and minus infinite are specified respectively with
the `+` and `-` strings. See the documentation for more information.

This feature is important because it allows us to use sorted sets as a generic
index. For example, if you want to index elements by a 128-bit unsigned
integer argument, all you need to do is to add elements into a sorted
set with the same score (for example 0) but with a 16 byte prefix
consisting of **the 128 bit number in big endian**. Since numbers in big
endian, when ordered lexicographically (in raw bytes order) are actually
ordered numerically as well, you can ask for ranges in the 128 bit space,
and get the element's value discarding the prefix

Updating the score: leaderboards
---

Just a final note about sorted sets before switching to the next topic.
Sorted sets' scores can be updated at any time. Just calling [`ZADD`]() against
an element already included in the sorted set will update its score
(and position) with O(log(N)) time complexity.  As such, sorted sets are suitable
when there are tons of updates.

Because of this characteristic a common use case is leaderboards.
The typical application is a Facebook game where you combine the ability to
take users sorted by their high score, plus the get-rank operation, in order
to show the top-N users, and the user rank in the leader board (e.g., "you are
the #4932 best score here").

title: Examples

role: example

text:
* There are two ways we can use a sorted set to represent a leaderboard. If we know a racer's new score, we can update it directly via the [`ZADD`]() command. However, if we want to add points to an existing score, we can use the [`ZINCRBY`]() command.
#### Code Examples

Practical pattern: Use ZADD to set scores and ZINCRBY to increment them when you need to update leaderboards with atomic operations

**Difficulty:** Intermediate

**Builds upon:** zadd

**Commands:** ZADD, ZINCRBY

**Complexity:**
- ZADD: O(log(N)
- ZINCRBY: O(log(N)

**Redis CLI:**

[code example]

**Available in:** Redis CLI, C# (Synchronous), Go, Java (Asynchronous - Lettuce), Java (Synchronous - Jedis), JavaScript (Node.js), PHP, Python

**C# (Synchronous):**

[code example]

**Go:**

[code example]

**Java (Asynchronous - Lettuce):**

[code example]

**Java (Synchronous - Jedis):**

[code example]

**JavaScript (Node.js):**

[code example]

**PHP:**

[code example]

**Python:**

[code example]

You'll see that [`ZADD`]() returns 0 when the member already exists (the score is updated), while [`ZINCRBY`]() returns the new score. The score for racer Henshaw went from 100, was changed to 150 with no regard for what score was there before, and then was incremented by 50 to 200.

title: Performance

role: performance

text:
Most sorted set operations are O(log(n)), where _n_ is the number of members.

Exercise some caution when running the [`ZRANGE`]() command with large returns values (e.g., in the tens of thousands or more).
This command's time complexity is O(log(n) + m), where _m_ is the number of results returned.

title: Alternatives

text:
Redis sorted sets are sometimes used for indexing other Redis data structures.
If you need to index and query your data, consider the [JSON]() data type and the [Redis Search]() features.

title: Learn more

role: related

text:
* [Redis Sorted Sets Explained](https://www.youtube.com/watch?v=MUKlxdBQZ7g) is an entertaining introduction to sorted sets in Redis.
* [Redis University's RU101](https://university.redis.com/courses/ru101/) explores Redis sorted sets in detail.

code:
> ZADD racer_scores 10 "Norem"
(integer) 1
> ZADD racer_scores 12 "Castilla"
(integer) 1
> ZADD racer_scores 8 "Sam-Bodden" 10 "Royce" 6 "Ford" 14 "Prickett"
(integer) 4

section_id: sorted-set-command-summary

code:
bool res1 = db.SortedSetAdd("racer_scores", "Norem", 10);
        Console.WriteLine(res1); // >>> True

        bool res2 = db.SortedSetAdd("racer_scores", "Castilla", 12);
        Console.WriteLine(res2); // >>> True

        long res3 = db.SortedSetAdd("racer_scores", [
            new("Sam-Bodden", 8),
            new("Royce", 10),
            new("Ford", 6),
            new("Prickett", 14),
            new("Castilla", 12)
        ]);
        Console.WriteLine(res3); // >>> 4

code:
res1, err := rdb.ZAdd(ctx, "racer_scores",
		redis.Z{Member: "Norem", Score: 10},
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res1) // >>> 1

	res2, err := rdb.ZAdd(ctx, "racer_scores",
		redis.Z{Member: "Castilla", Score: 12},
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res2) // >>> 1

	res3, err := rdb.ZAdd(ctx, "racer_scores",
		redis.Z{Member: "Norem", Score: 10},
		redis.Z{Member: "Sam-Bodden", Score: 8},
		redis.Z{Member: "Royce", Score: 10},
		redis.Z{Member: "Ford", Score: 6},
		redis.Z{Member: "Prickett", Score: 14},
		redis.Z{Member: "Castilla", Score: 12},
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res3) // >>> 4

code:
CompletableFuture<Void> zadd = asyncCommands.zadd("racer_scores", ScoredValue.just(10d, "Norem"))
                    .thenCompose(res1 -> {
                        System.out.println(res1); // >>> 1

                        return asyncCommands.zadd("racer_scores", ScoredValue.just(12d, "Castilla"));
                    }).thenCompose(res2 -> {
                        System.out.println(res2); // >>> 1

                        return asyncCommands.zadd("racer_scores", ScoredValue.just(8d, "Sam-Bodden"),
                                ScoredValue.just(10d, "Royce"), ScoredValue.just(6d, "Ford"),
                                ScoredValue.just(14d, "Prickett"));
                    })
                    .thenAccept(System.out::println) // >>> 4
                    .toCompletableFuture();

code:
long res1 = jedis.zadd("racer_scores", 10d, "Norem");
    System.out.println(res1); // >>> 1

    long res2 = jedis.zadd("racer_scores", 12d, "Castilla");
    System.out.println(res2); // >>> 1

    long res3 = jedis.zadd("racer_scores", new HashMap<String,Double>() {{
      put("Sam-Bodden", 8d);
      put("Royce", 10d);
      put("Ford", 6d);
      put("Prickett", 14d);
      put("Castilla", 12d);
    }});
    System.out.println(res3); // >>> 4

code:
const res1 = await client.zAdd('racer_scores', { score: 10, value: 'Norem' });
console.log(res1);  // >>> 1

const res2 = await client.zAdd('racer_scores', { score: 12, value: 'Castilla' });
console.log(res2);  // >>> 1

const res3 = await client.zAdd('racer_scores', [
  { score: 8, value: 'Sam-Bodden' },
  { score: 10, value: 'Royce' },
  { score: 6, value: 'Ford' },
  { score: 14, value: 'Prickett' },
  { score: 12, value: 'Castilla' }
]);
console.log(res3);  // >>> 4

code:
$res1 = $r->zadd('racer_scores', ['Norem' => 10]);
        echo $res1 . PHP_EOL;
        // >>> 1

        $res2 = $r->zadd('racer_scores', ['Castilla' => 12]);
        echo $res2 . PHP_EOL;
        // >>> 1

        $res3 = $r->zadd('racer_scores', [
            'Sam-Bodden' => 8,
            'Royce' => 10,
            'Ford' => 6,
            'Prickett' => 14,
            'Castilla' => 12,
        ]);
        echo $res3 . PHP_EOL;
        // >>> 4

code:
res1 = r.zadd("racer_scores", {"Norem": 10})
print(res1)  # >>> 1

res2 = r.zadd("racer_scores", {"Castilla": 12})
print(res2)  # >>> 1

res3 = r.zadd(
    "racer_scores",
    {"Sam-Bodden": 8, "Royce": 10, "Ford": 6, "Prickett": 14, "Castilla": 12},
)
print(res3)  # >>> 4

code:
> ZRANGE racer_scores 0 -1
1) "Ford"
2) "Sam-Bodden"
3) "Norem"
4) "Royce"
5) "Castilla"
6) "Prickett"
> ZREVRANGE racer_scores 0 -1
1) "Prickett"
2) "Castilla"
3) "Royce"
4) "Norem"
5) "Sam-Bodden"
6) "Ford"

code:
RedisValue[] res4 = db.SortedSetRangeByRank("racer_scores", 0, -1);
        Console.WriteLine(string.Join(", ", res4)); // >>> Ford, Sam-Bodden, Norem, Royce, Castilla, Prickett

        RedisValue[] res5 = db.SortedSetRangeByRank("racer_scores", 0, -1, Order.Descending);
        Console.WriteLine(string.Join(", ", res5)); // >>> Prickett, Castilla, Royce, Norem, Sam-Bodden, Ford

code:
res4, err := rdb.ZRange(ctx, "racer_scores", 0, -1).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res4)
	// >>> [Ford Sam-Bodden Norem Royce Castilla Prickett]

	res5, err := rdb.ZRevRange(ctx, "racer_scores", 0, -1).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res5)
	// >>> [Prickett Castilla Royce Norem Sam-Bodden Ford]

code:
CompletableFuture<Void> zrange = asyncCommands.zrange("racer_scores", 0, -1).thenCompose(res3 -> {
                System.out.println(res3);
                // >>> [Ford, Sam-Bodden, Norem, Royce, Castilla, Prickett]

                return asyncCommands.zrevrange("racer_scores", 0, -1);
            })
                    .thenAccept(System.out::println)
                    // >>> [Prickett, Castilla, Royce, Norem, Sam-Bodden, Ford]
                    .toCompletableFuture();

code:
List<String> res4 = jedis.zrange("racer_scores", 0, -1);
    System.out.println(res4); // >>> [Ford, Sam-Bodden, Norem, Royce, Castil, Castilla, Prickett]

    List<String> res5 = jedis.zrevrange("racer_scores", 0, -1);
    System.out.println(res5); // >>> [Prickett, Castilla, Castil, Royce, Norem, Sam-Bodden, Ford]

code:
const res4 = await client.zRange('racer_scores', 0, -1);
console.log(res4);  // >>> ['Ford', 'Sam-Bodden', 'Norem', 'Royce', 'Castilla', 'Prickett']

code:
$res4 = $r->zrange('racer_scores', 0, -1);
        echo json_encode($res4) . PHP_EOL;
        // >>> ["Ford","Sam-Bodden","Norem","Royce","Castilla","Prickett"]

        $res5 = $r->zrevrange('racer_scores', 0, -1);
        echo json_encode($res5) . PHP_EOL;
        // >>> ["Prickett","Castilla","Royce","Norem","Sam-Bodden","Ford"]

code:
res4 = r.zrange("racer_scores", 0, -1)
print(res4)  # >>> ['Ford', 'Sam-Bodden', 'Norem', 'Royce', 'Castilla', 'Prickett']

res5 = r.zrevrange("racer_scores", 0, -1)
print(res5)  # >>> ['Prickett', 'Castilla', 'Royce', 'Norem', 'Sam-Bodden', 'Ford']

code:
SortedSetEntry[] res6 = db.SortedSetRangeByRankWithScores("racer_scores", 0, -1);
        Console.WriteLine(string.Join(", ", res6)); // >>> Ford: 6, Sam-Bodden: 8, Norem: 10, Royce: 10, Castilla: 12, Prickett: 14

code:
res6, err := rdb.ZRangeWithScores(ctx, "racer_scores", 0, -1).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res6)
	// >>> [{6 Ford} {8 Sam-Bodden} {10 Norem} {10 Royce} {12 Castilla} {14 Prickett}]

code:
CompletableFuture<Void> zrangeWithScores = asyncCommands.zrangeWithScores("racer_scores", 0, -1)
                    .thenAccept(System.out::println)
                    // >>> [ScoredValue[6.000000, Ford], ScoredValue[8.000000, Sam-Bodden]...
                    .toCompletableFuture();

code:
List<Tuple> res6 = jedis.zrangeWithScores("racer_scores", 0, -1);
    System.out.println(res6); // >>> [[Ford,6.0], [Sam-Bodden,8.0], [Norem,10.0], [Royce,10.0], [Castil,12.0], [Castilla,12.0], [Prickett,14.0]]

code:
const res6 = await client.zRangeWithScores('racer_scores', 0, -1);
console.log(res6);
// >>> [
//       { value: 'Ford', score: 6 }, { value: 'Sam-Bodden', score: 8 },
//       { value: 'Norem', score: 10 }, { value: 'Royce', score: 10 },
//       { value: 'Castilla', score: 12 }, { value: 'Prickett', score: 14 }
// ]

code:
$res6 = $r->zrange('racer_scores', 0, -1,[
            'withscores' => true,
        ]);
        echo json_encode($res6) . PHP_EOL;
        // >>> {"Ford":"6","Sam-Bodden":"8","Norem":"10","Royce":"10","Castilla":"12","Prickett":"14"}

code:
> ZRANGEBYSCORE racer_scores -inf 10
1) "Ford"
2) "Sam-Bodden"
3) "Norem"
4) "Royce"

section_id: operating-on-ranges

code:
RedisValue[] res7 = db.SortedSetRangeByScore("racer_scores", double.NegativeInfinity, 10);
        Console.WriteLine(string.Join(", ", res7)); // >>> Ford, Sam-Bodden, Norem, Royce

code:
res7, err := rdb.ZRangeByScore(ctx, "racer_scores",
		&redis.ZRangeBy{Min: "-inf", Max: "10"},
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res7)
	// >>> [Ford Sam-Bodden Norem Royce]

code:
CompletableFuture<Void> zrangebyscore = asyncCommands
                    .zrangebyscore("racer_scores", Range.create(Double.MIN_VALUE, 10))
                    .thenAccept(System.out::println)
                    // >>> [Ford, Sam-Bodden, Norem, Royce]
                    .toCompletableFuture();

code:
List<String> res7 = jedis.zrangeByScore("racer_scores", Double.MIN_VALUE, 10d);
    System.out.println(res7); // >>> [Ford, Sam-Bodden, Norem, Royce]

code:
const res7 = await client.zRangeByScore('racer_scores', '-inf', 10);
console.log(res7);  // >>> ['Ford', 'Sam-Bodden', 'Norem', 'Royce']

code:
$res7 = $r->zrangebyscore('racer_scores', '-inf', 10);
        echo json_encode($res7) . PHP_EOL;
        // >>> ["Ford","Sam-Bodden","Norem","Royce"]

code:
res7 = r.zrangebyscore("racer_scores", "-inf", 10)
print(res7)  # >>> ['Ford', 'Sam-Bodden', 'Norem', 'Royce']

code:
> ZREM racer_scores "Castilla"
(integer) 1
> ZREMRANGEBYSCORE racer_scores -inf 9
(integer) 2
> ZRANGE racer_scores 0 -1
1) "Norem"
2) "Royce"
3) "Prickett"

code:
bool res8 = db.SortedSetRemove("racer_scores", "Castilla");
        Console.WriteLine(res8); // >>> True

        long res9 = db.SortedSetRemoveRangeByScore("racer_scores", double.NegativeInfinity, 9);
        Console.WriteLine(res9); // >>> 2

        RedisValue[] res10 = db.SortedSetRangeByRank("racer_scores", 0, -1);
        Console.WriteLine(string.Join(", ", res10)); // >>> Norem, Royce, Prickett

code:
res8, err := rdb.ZRem(ctx, "racer_scores", "Castilla").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res8) // >>> 1

	res9, err := rdb.ZRemRangeByScore(ctx, "racer_scores", "-inf", "9").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res9) // >>> 2

	res10, err := rdb.ZRange(ctx, "racer_scores", 0, -1).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res10)
	// >>> [Norem Royce Prickett]

code:
CompletableFuture<Void> zremrangebyscore = asyncCommands.zrem("racer_scores", "Castilla").thenCompose(res4 -> {
                System.out.println(res4); // >>> 1

                return asyncCommands.zremrangebyscore("racer_scores", Range.create(Double.MIN_VALUE, 9));
            }).thenCompose(res5 -> {
                System.out.println(res5); // >>> 2

                return asyncCommands.zrange("racer_scores", 0, -1);
            })
                    .thenAccept(System.out::println)
                    // >>> [Norem, Royce, Prickett]
                    .toCompletableFuture();

code:
long res8 = jedis.zrem("racer_scores", "Castilla");
    System.out.println(res8); // >>> 1

    long res9 = jedis.zremrangeByScore("racer_scores", Double.MIN_VALUE, 9d);
    System.out.println(res9); // >>> 2

    List<String> res10 = jedis.zrange("racer_scores", 0, -1);
    System.out.println(res10); // >>> [Norem, Royce, Prickett]

code:
const res8 = await client.zRem('racer_scores', 'Castilla');
console.log(res8);  // >>> 1

const res9 = await client.zRemRangeByScore('racer_scores', '-inf', 9);
console.log(res9);  // >>> 2

const res10 = await client.zRange('racer_scores', 0, -1);
console.log(res10);  // >>> ['Norem', 'Royce', 'Prickett']

code:
$res8 = $r->zrem('racer_scores', 'Castilla');
        echo $res8 . PHP_EOL;
        // >>> 1

        $res9 = $r->zremrangebyscore('racer_scores', '-inf', 9);
        echo $res9 . PHP_EOL;
        // >>> 2

        $res10 = $r->zrange('racer_scores', 0, -1);
        echo json_encode($res10) . PHP_EOL;
        // >>> ["Norem","Royce","Prickett"]

code:
res8 = r.zrem("racer_scores", "Castilla")
print(res8)  # >>> 1

res9 = r.zremrangebyscore("racer_scores", "-inf", 9)
print(res9)  # >>> 2

res10 = r.zrange("racer_scores", 0, -1)
print(res10)  # >>> ['Norem', 'Royce', 'Prickett']

code:
> ZRANK racer_scores "Norem"
(integer) 0
> ZREVRANK racer_scores "Norem"
(integer) 2

code:
long? res11 = db.SortedSetRank("racer_scores", "Norem");
        Console.WriteLine(res11); // >>> 0

        long? res12 = db.SortedSetRank("racer_scores", "Norem", Order.Descending);
        Console.WriteLine(res12); // >>> 2

code:
res11, err := rdb.ZRank(ctx, "racer_scores", "Norem").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res11) // >>> 0

	res12, err := rdb.ZRevRank(ctx, "racer_scores", "Norem").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res12) // >>> 2

code:
CompletableFuture<Void> zrank = asyncCommands.zrank("racer_scores", "Norem").thenCompose(res6 -> {
                System.out.println(res6); // >>> 0

                return asyncCommands.zrevrank("racer_scores", "Norem");
            })
                    .thenAccept(System.out::println) // >>> 2
                    .toCompletableFuture();

code:
long res11 = jedis.zrank("racer_scores", "Norem");
    System.out.println(res11); // >>> 0

    long res12 = jedis.zrevrank("racer_scores", "Norem");
    System.out.println(res12); // >>> 2

code:
const res11 = await client.zRank('racer_scores', 'Norem');
console.log(res11);  // >>> 0

const res12 = await client.zRevRank('racer_scores', 'Norem');
console.log(res12);  // >>> 2

code:
$res11 = $r->zrank('racer_scores', 'Norem');
        echo $res11 . PHP_EOL;
        // >>> 0

        $res12 = $r->zrevrank('racer_scores', 'Norem');
        echo $res12 . PHP_EOL;
        // >>> 2

code:
res11 = r.zrank("racer_scores", "Norem")
print(res11)  # >>> 0

res12 = r.zrevrank("racer_scores", "Norem")
print(res12)  # >>> 2

code:
> ZADD racer_scores 0 "Norem" 0 "Sam-Bodden" 0 "Royce" 0 "Castilla" 0 "Prickett" 0 "Ford"
(integer) 3
> ZRANGE racer_scores 0 -1
1) "Castilla"
2) "Ford"
3) "Norem"
4) "Prickett"
5) "Royce"
6) "Sam-Bodden"
> ZRANGEBYLEX racer_scores [A [L
1) "Castilla"
2) "Ford"

section_id: lexicographical-scores

code:
long res13 = db.SortedSetAdd("racer_scores", [
            new("Norem", 0),
            new("Sam-Bodden", 0),
            new("Royce", 0),
            new("Ford", 0),
            new("Prickett", 0),
            new("Castilla", 0)
        ]);
        Console.WriteLine(res13); // >>> 3

        RedisValue[] res14 = db.SortedSetRangeByRank("racer_scores", 0, -1);
        Console.WriteLine(string.Join(", ", res14)); // >>> Castilla, Ford, Norem, Pricket, Royce, Sam-Bodden

        RedisValue[] res15 = db.SortedSetRangeByValue("racer_scores", "A", "L", Exclude.None);
        Console.WriteLine(string.Join(", ", res15)); // >>> Castilla, Ford

code:
res13, err := rdb.ZAdd(ctx, "racer_scores",
		redis.Z{Member: "Norem", Score: 0},
		redis.Z{Member: "Sam-Bodden", Score: 0},
		redis.Z{Member: "Royce", Score: 0},
		redis.Z{Member: "Ford", Score: 0},
		redis.Z{Member: "Prickett", Score: 0},
		redis.Z{Member: "Castilla", Score: 0},
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res13) // >>> 3

	res14, err := rdb.ZRange(ctx, "racer_scores", 0, -1).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res14)
	// >>> [Castilla Ford Norem Prickett Royce Sam-Bodden]

	res15, err := rdb.ZRangeByLex(ctx, "racer_scores", &redis.ZRangeBy{
		Min: "[A", Max: "[L",
	}).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res15) // >>> [Castilla Ford]

code:
CompletableFuture<Void> zaddLex = asyncCommands.zadd("racer_scores", ScoredValue.just(0d, "Norem"),
                    ScoredValue.just(0d, "Sam-Bodden"), ScoredValue.just(0d, "Royce"), ScoredValue.just(0d, "Castilla"),
                    ScoredValue.just(0d, "Prickett"), ScoredValue.just(0d, "Ford")).thenCompose(res7 -> {
                        System.out.println(res7); // >>> 3

                        return asyncCommands.zrange("racer_scores", 0, -1);
                    }).thenCompose(res8 -> {
                        System.out.println(res8);
                        // >>> [Castilla, Ford, Norem, Prickett, Royce, Sam-Bodden]

                        return asyncCommands.zrangebylex("racer_scores", Range.create("A", "L"));
                    })
                    .thenAccept(System.out::println)
                    // >>> [Castilla, Ford]
                    .toCompletableFuture();

code:
long res13 = jedis.zadd("racer_scores", new HashMap<String,Double>() {{
      put("Norem", 0d);
      put("Sam-Bodden", 0d);
      put("Royce", 0d);
      put("Ford", 0d);
      put("Prickett", 0d);
      put("Castilla", 0d);
    }});
    System.out.println(res13); // >>> 3

    List<String> res14 = jedis.zrange("racer_scores", 0, -1);
    System.out.println(res14); // >>> [Castilla, Ford, Norem, Prickett, Royce, Sam-Bodden]

    List<String> res15 = jedis.zrangeByLex("racer_scores", "[A", "[L");
    System.out.println(res15); // >>> [Castilla, Ford]

code:
const res13 = await client.zAdd('racer_scores', [
  { score: 0, value: 'Norem' },
  { score: 0, value: 'Sam-Bodden' },
  { score: 0, value: 'Royce' },
  { score: 0, value: 'Ford' },
  { score: 0, value: 'Prickett' },
  { score: 0, value: 'Castilla' }
]);
console.log(res13);  // >>> 3

const res14 = await client.zRange('racer_scores', 0, -1);
console.log(res14);  // >>> ['Castilla', 'Ford', 'Norem', 'Prickett', 'Royce', 'Sam-Bodden']

const res15 = await client.zRangeByLex('racer_scores', '[A', '[L');
console.log(res15);  // >>> ['Castilla', 'Ford']

code:
$res13 = $r->zadd('racer_scores', [
            'Norem' => 0,
            'Sam-Bodden' => 0,
            'Royce' => 0,
            'Ford' => 0,
            'Prickett' => 0,
            'Castilla' => 0,
        ]);
        echo $res13 . PHP_EOL;
        // >>> 3

        $res14 = $r->zrange('racer_scores', 0, -1);
        echo json_encode($res14) . PHP_EOL;
        // >>> ["Castilla","Ford","Norem","Prickett","Royce","Sam-Bodden"]

        $res15 = $r->zrangebylex('racer_scores', '[A', '[L');
        echo json_encode($res15) . PHP_EOL;
        // >>> ["Castilla","Ford"]

code:
res13 = r.zadd(
    "racer_scores",
    {
        "Norem": 0,
        "Sam-Bodden": 0,
        "Royce": 0,
        "Ford": 0,
        "Prickett": 0,
        "Castilla": 0,
    },
)
print(res13)  # >>> 3

res14 = r.zrange("racer_scores", 0, -1)
print(res14)  # >>> ['Castilla', 'Ford', 'Norem', 'Prickett', 'Royce', 'Sam-Bodden']

res15 = r.zrangebylex("racer_scores", "[A", "[L")
print(res15)  # >>> ['Castilla', 'Ford']

code:
> ZADD racer_scores 100 "Wood"
(integer) 1
> ZADD racer_scores 100 "Henshaw"
(integer) 1
> ZADD racer_scores 150 "Henshaw"
(integer) 0
> ZINCRBY racer_scores 50 "Wood"
"150"
> ZINCRBY racer_scores 50 "Henshaw"
"200"

section_id: examples

code:
bool res16 = db.SortedSetAdd("racer_scores", "Wood", 100);
        Console.WriteLine(res16); // >>> True

        bool res17 = db.SortedSetAdd("racer_scores", "Henshaw", 100);
        Console.WriteLine(res17); // >>> True

        bool res18 = db.SortedSetAdd("racer_scores", "Henshaw", 150);
        Console.WriteLine(res18); // >>> False

        double res19 = db.SortedSetIncrement("racer_scores", "Wood", 50);
        Console.WriteLine(res19); // >>> 150.0

        double res20 = db.SortedSetIncrement("racer_scores", "Henshaw", 50);
        Console.WriteLine(res20); // >>> 200.0

code:
res16, err := rdb.ZAdd(ctx, "racer_scores",
		redis.Z{Member: "Wood", Score: 100},
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res16) // >>> 1

	res17, err := rdb.ZAdd(ctx, "racer_scores",
		redis.Z{Member: "Henshaw", Score: 100},
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res17) // >>> 1

	res18, err := rdb.ZAdd(ctx, "racer_scores",
		redis.Z{Member: "Henshaw", Score: 150},
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res18) // >>> 0

	res19, err := rdb.ZIncrBy(ctx, "racer_scores", 50, "Wood").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res19) // >>> 150

	res20, err := rdb.ZIncrBy(ctx, "racer_scores", 50, "Henshaw").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res20) // >>> 200

code:
CompletableFuture<Void> leaderboard = asyncCommands.zadd("racer_scores", ScoredValue.just(100, "Wood"))
                    .thenCompose(res9 -> {
                        System.out.println(res9); // >>> 1

                        return asyncCommands.zadd("racer_scores", ScoredValue.just(100, "Henshaw"));
                    }).thenCompose(res10 -> {
                        System.out.println(res10); // >>> 1

                        return asyncCommands.zadd("racer_scores", ScoredValue.just(150, "Henshaw"));
                    }).thenCompose(res11 -> {
                        System.out.println(res11); // >>> 0

                        return asyncCommands.zincrby("racer_scores", 50, "Wood");
                    }).thenCompose(res12 -> {
                        System.out.println(res12); // >>> 150

                        return asyncCommands.zincrby("racer_scores", 50, "Henshaw");
                    })
                    .thenAccept(System.out::println) // >>> 200
                    .toCompletableFuture();

code:
long res16 = jedis.zadd("racer_scores", 100d, "Wood");
    System.out.println(res16); // >>> 1

    long res17 = jedis.zadd("racer_scores", 100d, "Henshaw");
    System.out.println(res17); // >>> 1

    long res18 = jedis.zadd("racer_scores", 150d, "Henshaw");
    System.out.println(res18); // >>> 0

    double res19 = jedis.zincrby("racer_scores", 50d, "Wood");
    System.out.println(res19); // >>> 150.0

    double res20 = jedis.zincrby("racer_scores", 50d, "Henshaw");
    System.out.println(res20); // >>> 200.0

code:
const res16 = await client.zAdd('racer_scores', { score: 100, value: 'Wood' });
console.log(res16);  // >>> 1

const res17 = await client.zAdd('racer_scores', { score: 100, value: 'Henshaw' });
console.log(res17);  // >>> 1

const res18 = await client.zAdd('racer_scores', { score: 150, value: 'Henshaw' }, { nx: true });
console.log(res18);  // >>> 0

const res19 = await client.zIncrBy('racer_scores', 50, 'Wood');
console.log(res19);  // >>> 150.0

const res20 = await client.zIncrBy('racer_scores', 50, 'Henshaw');
console.log(res20);  // >>> 200.0

code:
$res16 = $r->zadd('racer_scores', ['Wood' => 100]);
        echo $res16 . PHP_EOL;
        // >>> 1

        $res17 = $r->zadd('racer_scores', ['Henshaw' => 100]);
        echo $res17 . PHP_EOL;
        // >>> 1

        $res18 = $r->zadd('racer_scores', ['Henshaw' => 150]);
        echo $res18 . PHP_EOL;
        // >>> 0

        $res19 = $r->zincrby('racer_scores', 50, 'Wood');
        echo $res19 . PHP_EOL;
        // >>> 150

        $res20 = $r->zincrby('racer_scores', 50, 'Henshaw');
        echo $res20 . PHP_EOL;
        // >>> 200

code:
res16 = r.zadd("racer_scores", {"Wood": 100})
print(res16)  # >>> 1

res17 = r.zadd("racer_scores", {"Henshaw": 100})
print(res17)  # >>> 1

res18 = r.zadd("racer_scores", {"Henshaw": 150})
print(res18)  # >>> 0

res19 = r.zincrby("racer_scores", 50, "Wood")
print(res19)  # >>> 150.0

res20 = r.zincrby("racer_scores", 50, "Henshaw")
print(res20)  # >>> 200.0