WebSocket Set Operations
The DBX WebSocket API provides real-time set operations for Redis. This guide covers all available set methods and their usage patterns.
Installation
npm install @0dbx/redis
Basic Usage
import { DbxWsClient } from "@0dbx/redis";
// Create WebSocket client
const wsClient = new DbxWsClient("ws://localhost:3000/redis_ws");
// Set operations
await wsClient.set.addMember("tags", "redis");
const members = await wsClient.set.getMembers("tags");
Connection Setup
Before using set operations, establish a WebSocket connection:
import { DBXWebSocketClient } from "@effortlesslabs/dbx";
const client = new DBXWebSocketClient({
url: "ws://localhost:8080/ws",
token: "your-jwt-token",
});
await client.connect();
Set Operations
SADD - Add Members to Set
Add one or more members to a set.
Request:{
"id": "req-1",
"method": "SADD",
"params": {
"key": "users:online",
"members": ["user:123", "user:456", "user:789"]
}
}
{
"id": "req-1",
"result": {
"added": 3
}
}
SREM - Remove Members from Set
Remove one or more members from a set.
Request:{
"id": "req-2",
"method": "SREM",
"params": {
"key": "users:online",
"members": ["user:123", "user:456"]
}
}
{
"id": "req-2",
"result": {
"removed": 2
}
}
SMEMBERS - Get All Set Members
Get all members of a set.
Request:{
"id": "req-3",
"method": "SMEMBERS",
"params": {
"key": "users:online"
}
}
{
"id": "req-3",
"result": {
"members": ["user:123", "user:456", "user:789"]
}
}
SISMEMBER - Check Member Exists
Check if a member exists in a set.
Request:{
"id": "req-4",
"method": "SISMEMBER",
"params": {
"key": "users:online",
"member": "user:123"
}
}
{
"id": "req-4",
"result": {
"exists": true
}
}
SCARD - Get Set Cardinality
Get the number of members in a set.
Request:{
"id": "req-5",
"method": "SCARD",
"params": {
"key": "users:online"
}
}
{
"id": "req-5",
"result": {
"cardinality": 3
}
}
SPOP - Remove and Return Random Member
Remove and return a random member from a set.
Request:{
"id": "req-6",
"method": "SPOP",
"params": {
"key": "users:online",
"count": 1
}
}
{
"id": "req-6",
"result": {
"members": ["user:456"]
}
}
SRANDMEMBER - Get Random Member
Get one or more random members from a set without removing them.
Request:{
"id": "req-7",
"method": "SRANDMEMBER",
"params": {
"key": "users:online",
"count": 2
}
}
{
"id": "req-7",
"result": {
"members": ["user:123", "user:789"]
}
}
SMOVE - Move Member Between Sets
Move a member from one set to another.
Request:{
"id": "req-8",
"method": "SMOVE",
"params": {
"source": "users:online",
"destination": "users:away",
"member": "user:123"
}
}
{
"id": "req-8",
"result": {
"moved": true
}
}
SINTER - Set Intersection
Get the intersection of multiple sets.
Request:{
"id": "req-9",
"method": "SINTER",
"params": {
"keys": ["users:online", "users:premium", "users:active"]
}
}
{
"id": "req-9",
"result": {
"members": ["user:123", "user:789"]
}
}
SINTERSTORE - Store Set Intersection
Store the intersection of multiple sets in a new set.
Request:{
"id": "req-10",
"method": "SINTERSTORE",
"params": {
"destination": "users:online_premium",
"keys": ["users:online", "users:premium"]
}
}
{
"id": "req-10",
"result": {
"cardinality": 2
}
}
SUNION - Set Union
Get the union of multiple sets.
Request:{
"id": "req-11",
"method": "SUNION",
"params": {
"keys": ["users:online", "users:away"]
}
}
{
"id": "req-11",
"result": {
"members": ["user:123", "user:456", "user:789", "user:101"]
}
}
SUNIONSTORE - Store Set Union
Store the union of multiple sets in a new set.
Request:{
"id": "req-12",
"method": "SUNIONSTORE",
"params": {
"destination": "users:all",
"keys": ["users:online", "users:away", "users:offline"]
}
}
{
"id": "req-12",
"result": {
"cardinality": 5
}
}
SDIFF - Set Difference
Get the difference between sets (members in first set but not in others).
Request:{
"id": "req-13",
"method": "SDIFF",
"params": {
"keys": ["users:online", "users:premium"]
}
}
{
"id": "req-13",
"result": {
"members": ["user:456"]
}
}
SDIFFSTORE - Store Set Difference
Store the difference between sets in a new set.
Request:{
"id": "req-14",
"method": "SDIFFSTORE",
"params": {
"destination": "users:online_non_premium",
"keys": ["users:online", "users:premium"]
}
}
{
"id": "req-14",
"result": {
"cardinality": 1
}
}
SSCAN - Scan Set Members
Iterate over set members using cursor-based pagination.
Request:{
"id": "req-15",
"method": "SSCAN",
"params": {
"key": "users:online",
"cursor": 0,
"count": 10,
"match": "user:*"
}
}
{
"id": "req-15",
"result": {
"cursor": 0,
"members": ["user:123", "user:456", "user:789"]
}
}
Error Handling
All WebSocket set operations return standardized error responses:
{
"id": "request-id",
"error": {
"code": "ERROR_CODE",
"message": "Human readable error message"
}
}
Common error codes:
KEY_NOT_FOUND
: The specified set key doesn't existTYPE_MISMATCH
: The key exists but is not a set typeINVALID_VALUE
: The value is not valid for the operationAUTHENTICATION_FAILED
: Invalid or missing authentication tokenRATE_LIMITED
: Request rate limit exceeded
TypeScript SDK Example
import { DbxWsClient } from "@0dbx/redis";
const wsClient = new DbxWsClient("ws://localhost:3000/redis_ws");
// Set operations
await wsClient.set.addMember("user:1:tags", "admin");
await wsClient.set.addMember("user:1:tags", "moderator");
const tags = await wsClient.set.getMembers("user:1:tags");
console.log(tags); // ["admin", "moderator"]
Best Practices
- Set Naming: Use descriptive set names that clearly indicate their purpose
- Member Uniqueness: Remember that sets only store unique members
- Batch Operations: Use SADD/SREM with multiple members for efficiency
- Memory Usage: Be mindful of set size as all members are loaded into memory
- Key Expiration: Set appropriate TTL on set keys for temporary data
- Set Operations: Use intersection, union, and difference operations for complex queries
Performance Considerations
- Set operations are generally very fast for membership testing
- SMEMBERS can be expensive for large sets - consider using SSCAN for iteration
- Set operations (SINTER, SUNION, SDIFF) are O(N) where N is the size of the smallest set
- SPOP and SRANDMEMBER are O(1) operations
- Consider using set partitioning for very large datasets
- Set operations are atomic, making them suitable for concurrent access patterns
Common Use Cases
User Sessions
// Track online users
await client.set.sadd("users:online", [userId]);
// Check if user is online
const isOnline = await client.set.sismember("users:online", userId);
// Get online user count
const onlineCount = await client.set.scard("users:online");
Tags and Categories
// Add tags to a post
await client.set.sadd("post:123:tags", ["javascript", "redis", "tutorial"]);
// Get all tags for a post
const tags = await client.set.smembers("post:123:tags");
// Find posts with specific tags
const taggedPosts = await client.set.sinter(["tag:javascript:posts", "tag:redis:posts"]);
Unique Collections
// Track unique visitors
await client.set.sadd("site:visitors", [visitorId]);
// Get unique visitor count
const uniqueVisitors = await client.set.scard("site:visitors");
// Check if visitor has been before
const isReturning = await client.set.sismember("site:visitors", visitorId);