Scanning
Walk keys, hashes, sets and sorted sets as lazy Streams over cursors.
Redis scans return a few entries and a cursor. The scan methods on redis hide the cursor and give you a Stream that asks for the next page when you pull. Take only what you need and the rest is never fetched.
Example (Collecting the First 20 Matching Keys)
import { , } from "effect";
import { } from "@effect-kit/redis";
const = .(function* () {
const = yield* ;
const = yield*
.({ : "user:*", : 100 })
.pipe(.(20), .);
return .(() => new ().());
});match is a glob pattern and count is a hint for the page size. scanKeys also takes type to filter by key type. Keys are Uint8Array, so decode them before use.
Scans can repeat keys
A scan is not a snapshot. A key can appear more than once, and keys added or removed during the scan can be missed or seen. Deduplicate if repeats matter.
Scanning one collection
Each collection type has its own stream.
| Method | Element type |
|---|---|
redis.scanKeys(options?) | Uint8Array |
redis.scanHash(key, options?) | readonly [field, value] as Uint8Array pairs |
redis.scanHashFields(key, options?) | Uint8Array field names |
redis.scanSet(key, options?) | Uint8Array members |
redis.scanSortedSet(key, options?) | readonly [member, score], member as Uint8Array and score as string |
Example (Streaming a Sorted Set)
import { , } from "effect";
import { } from "@effect-kit/redis";
const = .(function* () {
const = yield* ;
yield* .("leaderboard", [
[1.5, "ada"],
[2, "lin"],
]);
const entries = yield* .(.("leaderboard"));
return ;
});Scores come back as strings.
Paging by hand
redis.scan, redis.hscan, redis.sscan and redis.zscan run one command and return a ScanPage with a cursor string and the entries for that page. The cursor is an opaque decimal string. Use these when you must store the cursor between requests.
On a cluster, scanKeys walks the primary nodes one after another. See scanning a cluster.