From 2c9ad2e772fc444c2cbd0c4119d9bfbe399e2213 Mon Sep 17 00:00:00 2001 From: Nikolay Karadzhov Date: Mon, 5 May 2025 11:35:41 +0300 Subject: [PATCH] chore(examples): fix examples for v5 (#2938) --- examples/README.md | 14 +++++----- examples/blocking-list-pop.js | 5 ++-- examples/command-with-modifiers.js | 2 +- examples/connect-to-cluster.js | 5 ++-- examples/dump-and-restore.js | 6 ++++ examples/get-server-time.js | 10 +++++-- examples/hyperloglog.js | 4 +-- examples/lua-multi-incr.js | 8 ++++-- examples/managing-json.js | 11 ++++++-- examples/package.json | 4 +-- examples/search-hashes.js | 8 +++--- examples/search-json.js | 16 +++++------ examples/search-knn.js | 6 ++-- examples/set-scan.js | 12 ++++++-- examples/sorted-set.js | 28 +++++++++++++++++-- examples/stream-consumer-group.js | 16 +++++------ examples/time-series.js | 10 +++---- examples/topk.js | 12 ++++---- .../transaction-with-arbitrary-commands.js | 27 ++++++++++++------ examples/transaction-with-watch.js | 4 ++- 20 files changed, 133 insertions(+), 75 deletions(-) diff --git a/examples/README.md b/examples/README.md index 1080f424da..47c9912fd3 100644 --- a/examples/README.md +++ b/examples/README.md @@ -40,12 +40,12 @@ We'd love to see more examples here. If you have an idea that you'd like to see To set up the examples folder so that you can run an example / develop one of your own: -``` -$ git clone https://github.com/redis/node-redis.git -$ cd node-redis -$ npm install -ws && npm run build-all -$ cd examples -$ npm install +```bash +git clone https://github.com/redis/node-redis.git +cd node-redis +npm install -ws && npm run build +cd examples +npm install ``` ### Coding Guidelines for Examples @@ -91,5 +91,5 @@ await client.connect(); // Add your example code here... -client.destroy(); +client.close(); ``` diff --git a/examples/blocking-list-pop.js b/examples/blocking-list-pop.js index ec9bec4d63..f29a409398 100644 --- a/examples/blocking-list-pop.js +++ b/examples/blocking-list-pop.js @@ -4,16 +4,15 @@ // The script will be blocked until the LPUSH command is executed. // After which we log the list and quit the client. -import { createClient, commandOptions } from 'redis'; +import { createClientPool } from 'redis'; -const client = createClient(); +const client = createClientPool(); await client.connect(); const keyName = 'keyName'; const blpopPromise = client.blPop( - commandOptions({ isolated: true }), keyName, 0 ); diff --git a/examples/command-with-modifiers.js b/examples/command-with-modifiers.js index 31106b17e4..356304722c 100644 --- a/examples/command-with-modifiers.js +++ b/examples/command-with-modifiers.js @@ -1,7 +1,7 @@ // Define a custom script that shows example of SET command // with several modifiers. -import { createClient } from '../packages/client'; +import { createClient } from 'redis'; const client = createClient(); diff --git a/examples/connect-to-cluster.js b/examples/connect-to-cluster.js index 98655497c9..86e45b8796 100644 --- a/examples/connect-to-cluster.js +++ b/examples/connect-to-cluster.js @@ -1,7 +1,7 @@ // This is an example script to connect to a running cluster. // After connecting to the cluster the code sets and get a value. -// To setup this cluster you can follow the guide here: +// To setup this cluster you can follow the guide here: // https://redis.io/docs/manual/scaling/ // In this guide the ports which are being used are 7000 - 7005 @@ -29,5 +29,4 @@ await cluster.connect(); await cluster.set('hello', 'cluster'); const value = await cluster.get('hello'); console.log(value); - -await cluster.quit(); +await cluster.close(); diff --git a/examples/dump-and-restore.js b/examples/dump-and-restore.js index c2ee7f1e19..f464fd38be 100644 --- a/examples/dump-and-restore.js +++ b/examples/dump-and-restore.js @@ -12,6 +12,12 @@ const client = await createClient({ console.log('Redis Client Error', err); }).connect(); +// Make sure the source key exists +await client.set('source', 'value'); + +// Make sure destination doesnt exist +await client.del('destination'); + // DUMP a specific key into a local variable const dump = await client.dump('source'); diff --git a/examples/get-server-time.js b/examples/get-server-time.js index 0e32c1296a..752264df34 100644 --- a/examples/get-server-time.js +++ b/examples/get-server-time.js @@ -6,7 +6,13 @@ const client = createClient(); await client.connect(); const serverTime = await client.time(); -// 2022-02-25T12:57:40.000Z { microseconds: 351346 } +// In v5, TIME returns [unixTimestamp: string, microseconds: string] instead of Date +// Example: ['1708956789', '123456'] console.log(serverTime); -client.destroy(); +// Convert to JavaScript Date if needed +const [seconds, microseconds] = serverTime; +const date = new Date(parseInt(seconds) * 1000 + parseInt(microseconds) / 1000); +console.log('Converted to Date:', date); + +client.close(); diff --git a/examples/hyperloglog.js b/examples/hyperloglog.js index 027112a08b..1f8f04f2a6 100644 --- a/examples/hyperloglog.js +++ b/examples/hyperloglog.js @@ -9,7 +9,7 @@ const client = createClient(); await client.connect(); // Use `pfAdd` to add an element to a Hyperloglog, creating the Hyperloglog if necessary. -// await client.pfAdd(key, value) +// await client.pfAdd(key, value) // returns 1 or 0 // To get a count, the `pfCount` method is used. // await client.pfCount(key) @@ -48,4 +48,4 @@ try { console.error(e); } -client.destroy(); +client.close(); diff --git a/examples/lua-multi-incr.js b/examples/lua-multi-incr.js index 5cf3914200..71b12bdab0 100644 --- a/examples/lua-multi-incr.js +++ b/examples/lua-multi-incr.js @@ -12,9 +12,11 @@ const client = createClient({ 'redis.pcall("INCRBY", KEYS[1], ARGV[1]),' + 'redis.pcall("INCRBY", KEYS[2], ARGV[1])' + '}', - transformArguments(key1, key2, increment) { - return [key1, key2, increment.toString()]; - }, + parseCommand(parser, key1, key2, increment) { + parser.pushKey(key1); + parser.pushKey(key2); + parser.push(increment.toString()); + }, }), }, }); diff --git a/examples/managing-json.js b/examples/managing-json.js index a28a0ee510..0f1eb3b3c2 100644 --- a/examples/managing-json.js +++ b/examples/managing-json.js @@ -57,7 +57,7 @@ results = await client.json.get('noderedis:jsondata', { }); // Goldie is 3 years old now. -console.log(`Goldie is ${JSON.stringify(results[0])} years old now.`); +console.log(`Goldie is ${JSON.parse(results)[0]} years old now.`); // Add a new pet... await client.json.arrAppend('noderedis:jsondata', '$.pets', { @@ -68,9 +68,14 @@ await client.json.arrAppend('noderedis:jsondata', '$.pets', { }); // How many pets do we have now? -const numPets = await client.json.arrLen('noderedis:jsondata', '$.pets'); +const numPets = await client.json.arrLen('noderedis:jsondata', { path: '$.pets' }); // We now have 4 pets. console.log(`We now have ${numPets} pets.`); -client.destroy(); +const rex = { name: 'Rex', species: 'dog', age: 3, isMammal: true } + +const index = await client.json.arrIndex( 'noderedis:jsondata', '$.pets', rex); +console.log(`Rex is at index ${index}`); + +client.close(); diff --git a/examples/package.json b/examples/package.json index 91120774d9..c350c0b248 100644 --- a/examples/package.json +++ b/examples/package.json @@ -1,12 +1,12 @@ { "name": "node-redis-examples", "version": "1.0.0", - "description": "node-redis 4 example script", + "description": "node-redis 5 example script", "main": "index.js", "private": true, "type": "module", "dependencies": { - "redis": "../packages/client" + "redis": "../packages/redis" } } diff --git a/examples/search-hashes.js b/examples/search-hashes.js index f3aca6b8ae..a496fec823 100644 --- a/examples/search-hashes.js +++ b/examples/search-hashes.js @@ -1,7 +1,7 @@ // This example demonstrates how to use RediSearch to index and query data // stored in Redis hashes. -import { createClient, SchemaFieldTypes } from 'redis'; +import { createClient, SCHEMA_FIELD_TYPE } from 'redis'; const client = createClient(); @@ -12,11 +12,11 @@ try { // Documentation: https://redis.io/commands/ft.create/ await client.ft.create('idx:animals', { name: { - type: SchemaFieldTypes.TEXT, + type: SCHEMA_FIELD_TYPE.TEXT, SORTABLE: true }, - species: SchemaFieldTypes.TAG, - age: SchemaFieldTypes.NUMERIC + species: SCHEMA_FIELD_TYPE.TAG, + age: SCHEMA_FIELD_TYPE.NUMERIC }, { ON: 'HASH', PREFIX: 'noderedis:animals' diff --git a/examples/search-json.js b/examples/search-json.js index bff5b2cb36..60f2ff095e 100644 --- a/examples/search-json.js +++ b/examples/search-json.js @@ -3,7 +3,7 @@ // https://redis.io/docs/stack/search/ // https://redis.io/docs/stack/json/ -import { createClient, SchemaFieldTypes, AggregateGroupByReducers, AggregateSteps } from 'redis'; +import { createClient, SCHEMA_FIELD_TYPE, FT_AGGREGATE_GROUP_BY_REDUCERS, FT_AGGREGATE_STEPS } from 'redis'; const client = createClient(); @@ -14,19 +14,19 @@ await client.connect(); try { await client.ft.create('idx:users', { '$.name': { - type: SchemaFieldTypes.TEXT, + type: SCHEMA_FIELD_TYPE.TEXT, SORTABLE: true }, '$.age': { - type: SchemaFieldTypes.NUMERIC, + type: SCHEMA_FIELD_TYPE.NUMERIC, AS: 'age' }, '$.coins': { - type: SchemaFieldTypes.NUMERIC, + type: SCHEMA_FIELD_TYPE.NUMERIC, AS: 'coins' }, '$.email': { - type: SchemaFieldTypes.TAG, + type: SCHEMA_FIELD_TYPE.TAG, AS: 'email' } }, { @@ -119,13 +119,13 @@ console.log( JSON.stringify( await client.ft.aggregate('idx:users', '*', { STEPS: [{ - type: AggregateSteps.GROUPBY, + type: FT_AGGREGATE_STEPS.GROUPBY, REDUCE: [{ - type: AggregateGroupByReducers.AVG, + type: FT_AGGREGATE_GROUP_BY_REDUCERS.AVG, property: 'age', AS: 'averageAge' }, { - type: AggregateGroupByReducers.SUM, + type: FT_AGGREGATE_GROUP_BY_REDUCERS.SUM, property: 'coins', AS: 'totalCoins' }] diff --git a/examples/search-knn.js b/examples/search-knn.js index 49bd00d86d..abfce99018 100644 --- a/examples/search-knn.js +++ b/examples/search-knn.js @@ -4,7 +4,7 @@ // Inspired by RediSearch Python tests: // https://github.com/RediSearch/RediSearch/blob/06e36d48946ea08bd0d8b76394a4e82eeb919d78/tests/pytests/test_vecsim.py#L96 -import { createClient, SchemaFieldTypes, VectorAlgorithms } from 'redis'; +import { createClient, SCHEMA_FIELD_TYPE, SCHEMA_VECTOR_FIELD_ALGORITHM } from 'redis'; const client = createClient(); @@ -15,8 +15,8 @@ try { // Documentation: https://redis.io/docs/stack/search/reference/vectors/ await client.ft.create('idx:knn-example', { v: { - type: SchemaFieldTypes.VECTOR, - ALGORITHM: VectorAlgorithms.HNSW, + type: SCHEMA_FIELD_TYPE.VECTOR, + ALGORITHM: SCHEMA_VECTOR_FIELD_ALGORITHM.HNSW, TYPE: 'FLOAT32', DIM: 2, DISTANCE_METRIC: 'COSINE' diff --git a/examples/set-scan.js b/examples/set-scan.js index 0e379224d9..698b05983b 100644 --- a/examples/set-scan.js +++ b/examples/set-scan.js @@ -8,8 +8,14 @@ const client = createClient(); await client.connect(); const setName = 'setName'; -for await (const member of client.sScanIterator(setName)) { - console.log(member); + +for await (const members of client.sScanIterator(setName)) { + console.log('Batch of members:', members); + + // Process each member in the batch if needed + for (const member of members) { + console.log('Individual member:', member); + } } -client.destroy(); +client.close(); diff --git a/examples/sorted-set.js b/examples/sorted-set.js index 3fcc24b844..830427bea9 100644 --- a/examples/sorted-set.js +++ b/examples/sorted-set.js @@ -24,8 +24,30 @@ await client.zAdd('mysortedset', [ // Get all of the values/scores from the sorted set using // the scan approach: // https://redis.io/commands/zscan -for await (const memberWithScore of client.zScanIterator('mysortedset')) { - console.log(memberWithScore); +for await (const membersWithScores of client.zScanIterator('mysortedset')) { + console.log('Batch of members with scores:', membersWithScores); + + for (const memberWithScore of membersWithScores) { + console.log('Individual member with score:', memberWithScore); + } } -client.destroy(); +await client.zAdd('anothersortedset', [ + { + score: 99, + value: 'Ninety Nine' + }, + { + score: 102, + value: 'One Hundred and Two' + } +]); + +// Intersection of two sorted sets +const intersection = await client.zInter([ + { key: 'mysortedset', weight: 1 }, + { key: 'anothersortedset', weight: 1 } +]); +console.log('Intersection:', intersection); + +client.close(); diff --git a/examples/stream-consumer-group.js b/examples/stream-consumer-group.js index 0161b5b4d3..cf82b5e96a 100644 --- a/examples/stream-consumer-group.js +++ b/examples/stream-consumer-group.js @@ -20,7 +20,7 @@ // // $ node stream-consumer-group.js consumer2 -import { createClient, commandOptions } from 'redis'; +import { createClient } from 'redis'; const client = createClient(); @@ -46,14 +46,13 @@ try { console.log(`Starting consumer ${consumerName}.`); +const pool = client.createPool(); + while (true) { try { // https://redis.io/commands/xreadgroup/ - let response = await client.xReadGroup( - commandOptions({ - isolated: true - }), - 'myconsumergroup', + let response = await pool.xReadGroup( + 'myconsumergroup', consumerName, [ // XREADGROUP can read from multiple streams, starting at a // different ID for each... @@ -91,9 +90,10 @@ while (true) { // stream entry. // https://redis.io/commands/xack/ const entryId = response[0].messages[0].id; - await client.xAck('mystream', 'myconsumergroup', entryId); + const ackResult = await pool.xAck('mystream', 'myconsumergroup', entryId); - console.log(`Acknowledged processing of entry ${entryId}.`); + // ackResult will be 1 if the message was successfully acknowledged, 0 otherwise + console.log(`Acknowledged processing of entry ${entryId}. Result: ${ackResult}`); } else { // Response is null, we have read everything that is // in the stream right now... diff --git a/examples/time-series.js b/examples/time-series.js index 1d61ff9440..75df2736f8 100644 --- a/examples/time-series.js +++ b/examples/time-series.js @@ -2,7 +2,7 @@ // Requires the RedisTimeSeries module: https://redis.io/docs/stack/timeseries/ import { createClient } from 'redis'; -import { TimeSeriesDuplicatePolicies, TimeSeriesEncoding, TimeSeriesAggregationType } from '@redis/time-series'; +import { TIME_SERIES_DUPLICATE_POLICIES, TIME_SERIES_ENCODING, TIME_SERIES_AGGREGATION_TYPE } from '@redis/time-series'; const client = createClient(); @@ -14,8 +14,8 @@ try { // https://redis.io/commands/ts.create/ const created = await client.ts.create('mytimeseries', { RETENTION: 86400000, // 1 day in milliseconds - ENCODING: TimeSeriesEncoding.UNCOMPRESSED, // No compression - DUPLICATE_POLICY: TimeSeriesDuplicatePolicies.BLOCK // No duplicates + ENCODING: TIME_SERIES_ENCODING.UNCOMPRESSED, // No compression + DUPLICATE_POLICY: TIME_SERIES_DUPLICATE_POLICIES.BLOCK // No duplicates }); if (created === 'OK') { @@ -74,7 +74,7 @@ try { const rangeResponse = await client.ts.range('mytimeseries', fromTimestamp, toTimestamp, { // Group into 10 second averages. AGGREGATION: { - type: TimeSeriesAggregationType.AVERAGE, + type: TIME_SERIES_AGGREGATION_TYPE.AVG, timeBucket: 10000 } }); @@ -119,4 +119,4 @@ try { console.error(e); } -client.destroy(); +client.close(); diff --git a/examples/topk.js b/examples/topk.js index d09144c230..10cc29950e 100644 --- a/examples/topk.js +++ b/examples/topk.js @@ -1,4 +1,4 @@ -// This example demonstrates the use of the Top K +// This example demonstrates the use of the Top K // in the RedisBloom module (https://redis.io/docs/stack/bloom/) import { createClient } from 'redis'; @@ -95,10 +95,10 @@ const [ steve, suze, leibale, frederick ] = await client.topK.query('mytopk', [ 'frederick' ]); -console.log(`steve ${steve === 1 ? 'is': 'is not'} in the top 10.`); -console.log(`suze ${suze === 1 ? 'is': 'is not'} in the top 10.`); -console.log(`leibale ${leibale === 1 ? 'is': 'is not'} in the top 10.`); -console.log(`frederick ${frederick === 1 ? 'is': 'is not'} in the top 10.`); +console.log(`steve ${steve ? 'is': 'is not'} in the top 10.`); +console.log(`suze ${suze ? 'is': 'is not'} in the top 10.`); +console.log(`leibale ${leibale ? 'is': 'is not'} in the top 10.`); +console.log(`frederick ${frederick ? 'is': 'is not'} in the top 10.`); // Get count estimate for some team members with TOPK.COUNT: // https://redis.io/commands/topk.count/ @@ -110,4 +110,4 @@ const [ simonCount, lanceCount ] = await client.topK.count('mytopk', [ console.log(`Count estimate for simon: ${simonCount}.`); console.log(`Count estimate for lance: ${lanceCount}.`); -client.destroy(); +client.close(); diff --git a/examples/transaction-with-arbitrary-commands.js b/examples/transaction-with-arbitrary-commands.js index d68533205a..cc22a65967 100644 --- a/examples/transaction-with-arbitrary-commands.js +++ b/examples/transaction-with-arbitrary-commands.js @@ -1,6 +1,6 @@ -// How to mix and match supported commands that have named functions with +// How to mix and match supported commands that have named functions with // commands sent as arbitrary strings in the same transaction context. -// Use this when working with new Redis commands that haven't been added to +// Use this when working with new Redis commands that haven't been added to // node-redis yet, or when working with commands that have been added to Redis // by modules other than those directly supported by node-redis. @@ -23,18 +23,29 @@ await client.sendCommand(['hset', 'hash2', 'number', '3']); // In a transaction context, use addCommand to send arbitrary commands. // addCommand can be mixed and matched with named command functions as // shown. -const responses = await client - .multi() +const multi = client.multi() .hGetAll('hash2') .addCommand(['hset', 'hash3', 'number', '4']) - .hGet('hash3', 'number') - .exec(); + .hGet('hash3', 'number'); + +// exec() returns Array +const responses = await multi.exec(); // responses will be: // [ [Object: null prototype] { name: 'hash2', number: '3' }, 0, '4' ] -console.log(responses); +console.log('Using exec():', responses); + +// This is equivalent to multi.exec<'typed'>() +const typedResponses = await multi + .hGetAll('hash2') + .addCommand(['hset', 'hash3', 'number', '4']) + .hGet('hash3', 'number') + .execTyped(); + +// typedResponses will have more specific types +console.log('Using execTyped():', typedResponses); // Clean up fixtures. await client.del(['hash1', 'hash2', 'hash3']); -client.destroy(); +client.close(); diff --git a/examples/transaction-with-watch.js b/examples/transaction-with-watch.js index d92b910dfa..752d0b6a4e 100644 --- a/examples/transaction-with-watch.js +++ b/examples/transaction-with-watch.js @@ -13,9 +13,11 @@ function restrictFunctionCalls(fn, maxCalls) { const fn = restrictFunctionCalls(transaction, 4); +const pool = await client.createPool(); + async function transaction() { try { - await client.executeIsolated(async (isolatedClient) => { + await pool.execute(async (isolatedClient) => { await isolatedClient.watch('paymentId:1259'); const multi = isolatedClient .multi()