mirror of https://github.com/go-redis/redis.git
Add ScanType command to Scan with 'type' option
As of version 6.0 you can use this 'type' option to ask SCAN to only return objects that match a given type, allowing you to iterate through the database looking for keys of a specific type.
This commit is contained in:
parent
b3e0aa270a
commit
c2351b491a
17
commands.go
17
commands.go
|
@ -141,6 +141,7 @@ type Cmdable interface {
|
||||||
BitField(ctx context.Context, key string, args ...interface{}) *IntSliceCmd
|
BitField(ctx context.Context, key string, args ...interface{}) *IntSliceCmd
|
||||||
|
|
||||||
Scan(ctx context.Context, cursor uint64, match string, count int64) *ScanCmd
|
Scan(ctx context.Context, cursor uint64, match string, count int64) *ScanCmd
|
||||||
|
ScanType(ctx context.Context, cursor uint64, match string, count int64, keyType string) *ScanCmd
|
||||||
SScan(ctx context.Context, key string, cursor uint64, match string, count int64) *ScanCmd
|
SScan(ctx context.Context, key string, cursor uint64, match string, count int64) *ScanCmd
|
||||||
HScan(ctx context.Context, key string, cursor uint64, match string, count int64) *ScanCmd
|
HScan(ctx context.Context, key string, cursor uint64, match string, count int64) *ScanCmd
|
||||||
ZScan(ctx context.Context, key string, cursor uint64, match string, count int64) *ScanCmd
|
ZScan(ctx context.Context, key string, cursor uint64, match string, count int64) *ScanCmd
|
||||||
|
@ -965,6 +966,22 @@ func (c cmdable) Scan(ctx context.Context, cursor uint64, match string, count in
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c cmdable) ScanType(ctx context.Context, cursor uint64, match string, count int64, keyType string) *ScanCmd {
|
||||||
|
args := []interface{}{"scan", cursor}
|
||||||
|
if match != "" {
|
||||||
|
args = append(args, "match", match)
|
||||||
|
}
|
||||||
|
if count > 0 {
|
||||||
|
args = append(args, "count", count)
|
||||||
|
}
|
||||||
|
if keyType != "" {
|
||||||
|
args = append(args, "type", keyType)
|
||||||
|
}
|
||||||
|
cmd := NewScanCmd(ctx, c, args...)
|
||||||
|
_ = c(ctx, cmd)
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
func (c cmdable) SScan(ctx context.Context, key string, cursor uint64, match string, count int64) *ScanCmd {
|
func (c cmdable) SScan(ctx context.Context, key string, cursor uint64, match string, count int64) *ScanCmd {
|
||||||
args := []interface{}{"sscan", key, cursor}
|
args := []interface{}{"sscan", key, cursor}
|
||||||
if match != "" {
|
if match != "" {
|
||||||
|
|
|
@ -770,6 +770,18 @@ var _ = Describe("Commands", func() {
|
||||||
Expect(cursor).NotTo(BeZero())
|
Expect(cursor).NotTo(BeZero())
|
||||||
})
|
})
|
||||||
|
|
||||||
|
It("should ScanType", func() {
|
||||||
|
for i := 0; i < 1000; i++ {
|
||||||
|
set := client.Set(ctx, fmt.Sprintf("key%d", i), "hello", 0)
|
||||||
|
Expect(set.Err()).NotTo(HaveOccurred())
|
||||||
|
}
|
||||||
|
|
||||||
|
keys, cursor, err := client.ScanType(ctx, 0, "", 0, "string").Result()
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
Expect(keys).NotTo(BeEmpty())
|
||||||
|
Expect(cursor).NotTo(BeZero())
|
||||||
|
})
|
||||||
|
|
||||||
It("should SScan", func() {
|
It("should SScan", func() {
|
||||||
for i := 0; i < 1000; i++ {
|
for i := 0; i < 1000; i++ {
|
||||||
sadd := client.SAdd(ctx, "myset", fmt.Sprintf("member%d", i))
|
sadd := client.SAdd(ctx, "myset", fmt.Sprintf("member%d", i))
|
||||||
|
|
|
@ -248,6 +248,34 @@ func ExampleClient_Scan() {
|
||||||
// Output: found 33 keys
|
// Output: found 33 keys
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ExampleClient_ScanType() {
|
||||||
|
rdb.FlushDB(ctx)
|
||||||
|
for i := 0; i < 33; i++ {
|
||||||
|
err := rdb.Set(ctx, fmt.Sprintf("key%d", i), "value", 0).Err()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var cursor uint64
|
||||||
|
var n int
|
||||||
|
for {
|
||||||
|
var keys []string
|
||||||
|
var err error
|
||||||
|
keys, cursor, err = rdb.ScanType(ctx, cursor, "key*", 10, "string").Result()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
n += len(keys)
|
||||||
|
if cursor == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("found %d keys\n", n)
|
||||||
|
// Output: found 33 keys
|
||||||
|
}
|
||||||
|
|
||||||
func ExampleClient_Pipelined() {
|
func ExampleClient_Pipelined() {
|
||||||
var incr *redis.IntCmd
|
var incr *redis.IntCmd
|
||||||
_, err := rdb.Pipelined(ctx, func(pipe redis.Pipeliner) error {
|
_, err := rdb.Pipelined(ctx, func(pipe redis.Pipeliner) error {
|
||||||
|
|
Loading…
Reference in New Issue