Appearance
Redis 集
Redis 集简介
Redis 集是唯一字符串(成员)的无序集合。 您可以使用 Redis 集来高效地:
- 跟踪唯一项目(例如,跟踪访问给定博客文章的所有唯一 IP 地址)。
- 表示关系(例如,具有给定角色的所有用户的集合)。
- 执行常见的集操作,例如交集、并集和差集。
基本命令
- SADD 将新成员添加到集合中。
- SREM 将从集中删除指定的成员。
- SISMEMBER 测试字符串的集成员身份。
- SINTER 返回两个或多个集合共有的成员集(即交集)。
- SCARD 返回集合的大小 (也称为基数) 。
请参阅 set 命令的完整列表。
例子
- 存放法国和美国的自行车组。请注意, 如果添加已存在的成员,则将忽略该成员
bash
> 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
python
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
js
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
java
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
go
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
csharp
long res1 = db.SetAdd("bikes:racing:france", new RedisValue[] { "bike:1" });
Console.WriteLine(res1); // >>> 1
long res2 = db.SetAdd("bikes:racing:france", new RedisValue[] { "bike:1" });
Console.WriteLine(res2); // >>> 0
long res3 = db.SetAdd("bikes:racing:france", new RedisValue[] { "bike:2", "bike:3" });
Console.WriteLine(res3); // >>> 2
long res4 = db.SetAdd("bikes:racing:usa", new RedisValue[] { "bike:1", "bike:4" });
Console.WriteLine(res4); // >>> 2
- 检查 bike:1 或 bike:2 是否在美国比赛。
bash
> SISMEMBER bikes:racing:usa bike:1
(integer) 1
> SISMEMBER bikes:racing:usa bike:2
(integer) 0
python
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
js
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) // >>> true
const res6 = await client.sIsMember('bikes:racing:usa', 'bike:2')
console.log(res6) // >>> false
java
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
go
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
csharp
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
- 哪些自行车参加了两场比赛?
bash
> SINTER bikes:racing:france bikes:racing:usa
1) "bike:1"
python
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'}
js
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
const res5 = await client.sIsMember('bikes:racing:usa', 'bike:1')
console.log(res5) // >>> true
const res6 = await client.sIsMember('bikes:racing:usa', 'bike:2')
console.log(res6) // >>> false
const res7 = await client.sInter('bikes:racing:france', 'bikes:racing:usa')
console.log(res7) // >>> {'bike:1'}
const res8 = await client.sCard('bikes:racing:france')
console.log(res8) // >>> 3
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) // >>> true
const res12 = await client.smIsMember('bikes:racing:france', ['bike:2', 'bike:3', 'bike:4'])
console.log(res12) // >>> [true, true, false]
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.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']
debugger;
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
java
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]
go
res7, err := rdb.SInter(ctx, "bikes:racing:france", "bikes:racing:usa").Result()
if err != nil {
panic(err)
}
fmt.Println(res7) // >>> [bike:1]
csharp
long res7 = db.SetAdd("{bikes:racing}:france", new RedisValue[] { "bike:1", "bike:2", "bike:3" });
long res8 = db.SetAdd("{bikes:racing}:usa", new RedisValue[] { "bike:1", "bike:4" });
RedisValue[] res9 = db.SetCombine(SetOperation.Intersect, new RedisKey[] { "{bikes:racing}:france", "{bikes:racing}:usa" });
Console.WriteLine(string.Join(", ", res9)); // >>> bike:1
- 有多少辆自行车在法国比赛?
bash
> SCARD bikes:racing:france
(integer) 3
python
r.sadd("bikes:racing:france", "bike:1", "bike:2", "bike:3")
res8 = r.scard("bikes:racing:france")
print(res8) # >>> 3
js
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
java
jedis.sadd("bikes:racing:france", "bike:1", "bike:2", "bike:3");
long res8 = jedis.scard("bikes:racing:france");
System.out.println(res8); // >>> 3
go
res8, err := rdb.SCard(ctx, "bikes:racing:france").Result()
if err != nil {
panic(err)
}
fmt.Println(res8) // >>> 3
csharp
long res10 = db.SetAdd("bikes:racing:france", new RedisValue[] { "bike:1", "bike:2", "bike:3" });
long res11 = db.SetLength("bikes:racing:france");
Console.WriteLine(res11); // >>> 3
教程
SADD 命令将新元素添加到集合中。这也是可能的 对集合执行许多其他操作,例如测试给定元素 已经存在,执行 intersection、union 或 difference 多个集合,依此类推。
bash
> 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
python
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'}
js
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']
java
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]
go
res8, err := rdb.SCard(ctx, "bikes:racing:france").Result()
if err != nil {
panic(err)
}
fmt.Println(res8) // >>> 3
csharp
long res12 = db.SetAdd("bikes:racing:france", new RedisValue[] { "bike:1", "bike:2", "bike:3" });
RedisValue[] res13 = db.SetMembers("bikes:racing:france");
Console.WriteLine(string.Join(", ", res13)); // >>> bike:3, bike:2, bike:1
在这里,我向我的集合添加了三个元素,并告诉 Redis 返回所有 元素。套装没有订单保证。Redis 可以自由地返回 元素中。
Redis 具有用于测试集合成员资格的命令。这些命令可用于单个项目和多个项目:
bash
> 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
python
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]
js
const res11 = await client.sIsMember('bikes:racing:france', 'bike:1')
console.log(res11) // >>> true
const res12 = await client.smIsMember('bikes:racing:france', ['bike:2', 'bike:3', 'bike:4'])
console.log(res12) // >>> [true, true, false]
java
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]
go
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]
csharp
bool res14 = db.SetContains("bikes:racing:france", "bike:1");
Console.WriteLine(res14); // >>> true
bool[] res15 = db.SetContains("bikes:racing:france", new RedisValue[] { "bike:2", "bike:3", "bike:4" });
Console.WriteLine(string.Join(", ", res15)); // >>> True, True, False
我们还可以找到两组之间的差异。例如,我们可能希望 要了解哪些自行车在法国比赛,而不是在美国比赛:
bash
> SADD bikes:racing:usa bike:1 bike:4
(integer) 2
> SDIFF bikes:racing:france bikes:racing:usa
1) "bike:3"
2) "bike:2"
python
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'}
js
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' ]
java
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]
go
_, 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)
}
fmt.Println(res13) // >>> [bike:2 bike:3]
csharp
long res16 = db.SetAdd("{bikes:racing}:france", new RedisValue[] { "bike:1", "bike:2", "bike:3" });
long res17 = db.SetAdd("{bikes:racing}:usa", new RedisValue[] { "bike:1", "bike:4" });
RedisValue[] res18 = db.SetCombine(SetOperation.Difference, new RedisKey[] { "{bikes:racing}:france", "{bikes:racing}:usa" });
Console.WriteLine(string.Join(", ", res18)); // >>> bike:2, bike:3
还有其他一些重要的操作仍然很容易实现 使用正确的 Redis 命令。例如,我们可能需要一个包含所有 在法国、美国和其他一些比赛中参加自行车比赛。我们可以使用 SINTER 命令,该命令执行不同 集。除了 intersection 之外,您还可以执行 联合、差异等等。例如 如果我们添加第三个 race,我们可以看到其中一些命令正在运行:
bash
> 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"
python
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) # >>> {}
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'}
js
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']
java
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]
go
_, 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)
}
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)
}
fmt.Println(res18) // >>> [bike:2 bike:3]
csharp
long res19 = db.SetAdd("{bikes:racing}:france", new RedisValue[] { "bike:1", "bike:2", "bike:3" });
long res20 = db.SetAdd("{bikes:racing}:usa", new RedisValue[] { "bike:1", "bike:4" });
long res21 = db.SetAdd("{bikes:racing}:italy", new RedisValue[] { "bike:1", "bike:2", "bike:3", "bike:4" });
RedisValue[] res22 = db.SetCombine(SetOperation.Intersect, new RedisKey[] { "{bikes:racing}:france", "{bikes:racing}:usa", "{bikes:racing}:italy" });
Console.WriteLine(string.Join(", ", res22)); // >>> bike:1
RedisValue[] res23 = db.SetCombine(SetOperation.Union, new RedisKey[] { "{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, new RedisKey[] { "{bikes:racing}:france", "{bikes:racing}:usa", "{bikes:racing}:italy" });
Console.WriteLine(string.Join(", ", res24)); // >>> <empty set>
RedisValue[] res25 = db.SetCombine(SetOperation.Difference, new RedisKey[] { "{bikes:racing}:usa", "{bikes:racing}:france" });
Console.WriteLine(string.Join(", ", res25)); // >>> bike:4
RedisValue[] res26 = db.SetCombine(SetOperation.Difference, new RedisKey[] { "{bikes:racing}:france", "{bikes:racing}:usa" });
Console.WriteLine(string.Join(", ", res26)); // >>> bike:2, bike:3
您会注意到,当 SDIFF 命令的 所有集合之间的差异为空。您还会注意到 set 的顺序 传递给 SDIFF 很重要,因为差异不是交换的。
如果要从集中删除项目,可以使用 SREM 命令 从集中删除一个或多个项目,也可以使用 SPOP 命令 从集合中删除随机项。您还可以从 set 而不使用 SRANDMEMBER 命令将其删除:
bash
> 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"
python
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
js
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
java
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
go
_, 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>
csharp
long res27 = db.SetAdd("bikes:racing:france", new RedisValue[] { "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
限制
Redis 集的最大大小为 2^32 - 1 (4,294,967,295) 个成员。
性能
大多数集合操作(包括添加、删除和检查项是否为集合成员)都是 O(1)。 这意味着它们的效率很高。 但是,对于具有数十万个或更多成员的大型集,在运行 SMEMBERS 命令时应小心谨慎。 此命令为 O(n) ,并在单个响应中返回整个集合。 作为替代方法,请考虑使用 SSCAN,它允许您以迭代方式检索集的所有成员。
选择
对大型数据集(或流数据)进行成员资格检查可能会占用大量内存。 如果您关心内存使用并且不需要完美的精度,请考虑使用 Bloom 过滤器或 Cuckoo 过滤器作为 set 的替代方案。
Redis 集经常用作一种索引。 如果您需要索引和查询数据,请考虑 JSON 数据类型和 Redis 查询引擎功能。
了解更多信息
- Redis 集解释 和 Redis 集详解 是两个简短但详尽的视频解释,涵盖了 Redis 集。
- Redis 大学的 RU101 详细探讨了 Redis 集。