1
0
mirror of https://github.com/redis/node-redis.git synced 2025-08-06 02:15:48 +03:00

chore(examples): fix examples for v5 (#2938)

This commit is contained in:
Nikolay Karadzhov
2025-05-05 11:35:41 +03:00
committed by GitHub
parent bd5c230c62
commit 2c9ad2e772
20 changed files with 133 additions and 75 deletions

View File

@@ -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: To set up the examples folder so that you can run an example / develop one of your own:
``` ```bash
$ git clone https://github.com/redis/node-redis.git git clone https://github.com/redis/node-redis.git
$ cd node-redis cd node-redis
$ npm install -ws && npm run build-all npm install -ws && npm run build
$ cd examples cd examples
$ npm install npm install
``` ```
### Coding Guidelines for Examples ### Coding Guidelines for Examples
@@ -91,5 +91,5 @@ await client.connect();
// Add your example code here... // Add your example code here...
client.destroy(); client.close();
``` ```

View File

@@ -4,16 +4,15 @@
// The script will be blocked until the LPUSH command is executed. // The script will be blocked until the LPUSH command is executed.
// After which we log the list and quit the client. // 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(); await client.connect();
const keyName = 'keyName'; const keyName = 'keyName';
const blpopPromise = client.blPop( const blpopPromise = client.blPop(
commandOptions({ isolated: true }),
keyName, keyName,
0 0
); );

View File

@@ -1,7 +1,7 @@
// Define a custom script that shows example of SET command // Define a custom script that shows example of SET command
// with several modifiers. // with several modifiers.
import { createClient } from '../packages/client'; import { createClient } from 'redis';
const client = createClient(); const client = createClient();

View File

@@ -29,5 +29,4 @@ await cluster.connect();
await cluster.set('hello', 'cluster'); await cluster.set('hello', 'cluster');
const value = await cluster.get('hello'); const value = await cluster.get('hello');
console.log(value); console.log(value);
await cluster.close();
await cluster.quit();

View File

@@ -12,6 +12,12 @@ const client = await createClient({
console.log('Redis Client Error', err); console.log('Redis Client Error', err);
}).connect(); }).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 // DUMP a specific key into a local variable
const dump = await client.dump('source'); const dump = await client.dump('source');

View File

@@ -6,7 +6,13 @@ const client = createClient();
await client.connect(); await client.connect();
const serverTime = await client.time(); 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); 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();

View File

@@ -9,7 +9,7 @@ const client = createClient();
await client.connect(); await client.connect();
// Use `pfAdd` to add an element to a Hyperloglog, creating the Hyperloglog if necessary. // 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. // To get a count, the `pfCount` method is used.
// await client.pfCount(key) // await client.pfCount(key)
@@ -48,4 +48,4 @@ try {
console.error(e); console.error(e);
} }
client.destroy(); client.close();

View File

@@ -12,8 +12,10 @@ const client = createClient({
'redis.pcall("INCRBY", KEYS[1], ARGV[1]),' + 'redis.pcall("INCRBY", KEYS[1], ARGV[1]),' +
'redis.pcall("INCRBY", KEYS[2], ARGV[1])' + 'redis.pcall("INCRBY", KEYS[2], ARGV[1])' +
'}', '}',
transformArguments(key1, key2, increment) { parseCommand(parser, key1, key2, increment) {
return [key1, key2, increment.toString()]; parser.pushKey(key1);
parser.pushKey(key2);
parser.push(increment.toString());
}, },
}), }),
}, },

View File

@@ -57,7 +57,7 @@ results = await client.json.get('noderedis:jsondata', {
}); });
// Goldie is 3 years old now. // 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... // Add a new pet...
await client.json.arrAppend('noderedis:jsondata', '$.pets', { 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? // 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. // We now have 4 pets.
console.log(`We now have ${numPets} 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();

View File

@@ -1,12 +1,12 @@
{ {
"name": "node-redis-examples", "name": "node-redis-examples",
"version": "1.0.0", "version": "1.0.0",
"description": "node-redis 4 example script", "description": "node-redis 5 example script",
"main": "index.js", "main": "index.js",
"private": true, "private": true,
"type": "module", "type": "module",
"dependencies": { "dependencies": {
"redis": "../packages/client" "redis": "../packages/redis"
} }
} }

View File

@@ -1,7 +1,7 @@
// This example demonstrates how to use RediSearch to index and query data // This example demonstrates how to use RediSearch to index and query data
// stored in Redis hashes. // stored in Redis hashes.
import { createClient, SchemaFieldTypes } from 'redis'; import { createClient, SCHEMA_FIELD_TYPE } from 'redis';
const client = createClient(); const client = createClient();
@@ -12,11 +12,11 @@ try {
// Documentation: https://redis.io/commands/ft.create/ // Documentation: https://redis.io/commands/ft.create/
await client.ft.create('idx:animals', { await client.ft.create('idx:animals', {
name: { name: {
type: SchemaFieldTypes.TEXT, type: SCHEMA_FIELD_TYPE.TEXT,
SORTABLE: true SORTABLE: true
}, },
species: SchemaFieldTypes.TAG, species: SCHEMA_FIELD_TYPE.TAG,
age: SchemaFieldTypes.NUMERIC age: SCHEMA_FIELD_TYPE.NUMERIC
}, { }, {
ON: 'HASH', ON: 'HASH',
PREFIX: 'noderedis:animals' PREFIX: 'noderedis:animals'

View File

@@ -3,7 +3,7 @@
// https://redis.io/docs/stack/search/ // https://redis.io/docs/stack/search/
// https://redis.io/docs/stack/json/ // 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(); const client = createClient();
@@ -14,19 +14,19 @@ await client.connect();
try { try {
await client.ft.create('idx:users', { await client.ft.create('idx:users', {
'$.name': { '$.name': {
type: SchemaFieldTypes.TEXT, type: SCHEMA_FIELD_TYPE.TEXT,
SORTABLE: true SORTABLE: true
}, },
'$.age': { '$.age': {
type: SchemaFieldTypes.NUMERIC, type: SCHEMA_FIELD_TYPE.NUMERIC,
AS: 'age' AS: 'age'
}, },
'$.coins': { '$.coins': {
type: SchemaFieldTypes.NUMERIC, type: SCHEMA_FIELD_TYPE.NUMERIC,
AS: 'coins' AS: 'coins'
}, },
'$.email': { '$.email': {
type: SchemaFieldTypes.TAG, type: SCHEMA_FIELD_TYPE.TAG,
AS: 'email' AS: 'email'
} }
}, { }, {
@@ -119,13 +119,13 @@ console.log(
JSON.stringify( JSON.stringify(
await client.ft.aggregate('idx:users', '*', { await client.ft.aggregate('idx:users', '*', {
STEPS: [{ STEPS: [{
type: AggregateSteps.GROUPBY, type: FT_AGGREGATE_STEPS.GROUPBY,
REDUCE: [{ REDUCE: [{
type: AggregateGroupByReducers.AVG, type: FT_AGGREGATE_GROUP_BY_REDUCERS.AVG,
property: 'age', property: 'age',
AS: 'averageAge' AS: 'averageAge'
}, { }, {
type: AggregateGroupByReducers.SUM, type: FT_AGGREGATE_GROUP_BY_REDUCERS.SUM,
property: 'coins', property: 'coins',
AS: 'totalCoins' AS: 'totalCoins'
}] }]

View File

@@ -4,7 +4,7 @@
// Inspired by RediSearch Python tests: // Inspired by RediSearch Python tests:
// https://github.com/RediSearch/RediSearch/blob/06e36d48946ea08bd0d8b76394a4e82eeb919d78/tests/pytests/test_vecsim.py#L96 // 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(); const client = createClient();
@@ -15,8 +15,8 @@ try {
// Documentation: https://redis.io/docs/stack/search/reference/vectors/ // Documentation: https://redis.io/docs/stack/search/reference/vectors/
await client.ft.create('idx:knn-example', { await client.ft.create('idx:knn-example', {
v: { v: {
type: SchemaFieldTypes.VECTOR, type: SCHEMA_FIELD_TYPE.VECTOR,
ALGORITHM: VectorAlgorithms.HNSW, ALGORITHM: SCHEMA_VECTOR_FIELD_ALGORITHM.HNSW,
TYPE: 'FLOAT32', TYPE: 'FLOAT32',
DIM: 2, DIM: 2,
DISTANCE_METRIC: 'COSINE' DISTANCE_METRIC: 'COSINE'

View File

@@ -8,8 +8,14 @@ const client = createClient();
await client.connect(); await client.connect();
const setName = 'setName'; 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();

View File

@@ -24,8 +24,30 @@ await client.zAdd('mysortedset', [
// Get all of the values/scores from the sorted set using // Get all of the values/scores from the sorted set using
// the scan approach: // the scan approach:
// https://redis.io/commands/zscan // https://redis.io/commands/zscan
for await (const memberWithScore of client.zScanIterator('mysortedset')) { for await (const membersWithScores of client.zScanIterator('mysortedset')) {
console.log(memberWithScore); 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();

View File

@@ -20,7 +20,7 @@
// //
// $ node stream-consumer-group.js consumer2 // $ node stream-consumer-group.js consumer2
import { createClient, commandOptions } from 'redis'; import { createClient } from 'redis';
const client = createClient(); const client = createClient();
@@ -46,13 +46,12 @@ try {
console.log(`Starting consumer ${consumerName}.`); console.log(`Starting consumer ${consumerName}.`);
const pool = client.createPool();
while (true) { while (true) {
try { try {
// https://redis.io/commands/xreadgroup/ // https://redis.io/commands/xreadgroup/
let response = await client.xReadGroup( let response = await pool.xReadGroup(
commandOptions({
isolated: true
}),
'myconsumergroup', 'myconsumergroup',
consumerName, [ consumerName, [
// XREADGROUP can read from multiple streams, starting at a // XREADGROUP can read from multiple streams, starting at a
@@ -91,9 +90,10 @@ while (true) {
// stream entry. // stream entry.
// https://redis.io/commands/xack/ // https://redis.io/commands/xack/
const entryId = response[0].messages[0].id; 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 { } else {
// Response is null, we have read everything that is // Response is null, we have read everything that is
// in the stream right now... // in the stream right now...

View File

@@ -2,7 +2,7 @@
// Requires the RedisTimeSeries module: https://redis.io/docs/stack/timeseries/ // Requires the RedisTimeSeries module: https://redis.io/docs/stack/timeseries/
import { createClient } from 'redis'; 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(); const client = createClient();
@@ -14,8 +14,8 @@ try {
// https://redis.io/commands/ts.create/ // https://redis.io/commands/ts.create/
const created = await client.ts.create('mytimeseries', { const created = await client.ts.create('mytimeseries', {
RETENTION: 86400000, // 1 day in milliseconds RETENTION: 86400000, // 1 day in milliseconds
ENCODING: TimeSeriesEncoding.UNCOMPRESSED, // No compression ENCODING: TIME_SERIES_ENCODING.UNCOMPRESSED, // No compression
DUPLICATE_POLICY: TimeSeriesDuplicatePolicies.BLOCK // No duplicates DUPLICATE_POLICY: TIME_SERIES_DUPLICATE_POLICIES.BLOCK // No duplicates
}); });
if (created === 'OK') { if (created === 'OK') {
@@ -74,7 +74,7 @@ try {
const rangeResponse = await client.ts.range('mytimeseries', fromTimestamp, toTimestamp, { const rangeResponse = await client.ts.range('mytimeseries', fromTimestamp, toTimestamp, {
// Group into 10 second averages. // Group into 10 second averages.
AGGREGATION: { AGGREGATION: {
type: TimeSeriesAggregationType.AVERAGE, type: TIME_SERIES_AGGREGATION_TYPE.AVG,
timeBucket: 10000 timeBucket: 10000
} }
}); });
@@ -119,4 +119,4 @@ try {
console.error(e); console.error(e);
} }
client.destroy(); client.close();

View File

@@ -95,10 +95,10 @@ const [ steve, suze, leibale, frederick ] = await client.topK.query('mytopk', [
'frederick' 'frederick'
]); ]);
console.log(`steve ${steve === 1 ? 'is': 'is not'} in the top 10.`); console.log(`steve ${steve ? 'is': 'is not'} in the top 10.`);
console.log(`suze ${suze === 1 ? 'is': 'is not'} in the top 10.`); console.log(`suze ${suze ? 'is': 'is not'} in the top 10.`);
console.log(`leibale ${leibale === 1 ? 'is': 'is not'} in the top 10.`); console.log(`leibale ${leibale ? 'is': 'is not'} in the top 10.`);
console.log(`frederick ${frederick === 1 ? '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: // Get count estimate for some team members with TOPK.COUNT:
// https://redis.io/commands/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 simon: ${simonCount}.`);
console.log(`Count estimate for lance: ${lanceCount}.`); console.log(`Count estimate for lance: ${lanceCount}.`);
client.destroy(); client.close();

View File

@@ -23,18 +23,29 @@ await client.sendCommand(['hset', 'hash2', 'number', '3']);
// In a transaction context, use addCommand to send arbitrary commands. // In a transaction context, use addCommand to send arbitrary commands.
// addCommand can be mixed and matched with named command functions as // addCommand can be mixed and matched with named command functions as
// shown. // shown.
const responses = await client const multi = client.multi()
.multi()
.hGetAll('hash2') .hGetAll('hash2')
.addCommand(['hset', 'hash3', 'number', '4']) .addCommand(['hset', 'hash3', 'number', '4'])
.hGet('hash3', 'number') .hGet('hash3', 'number');
.exec();
// exec() returns Array<ReplyUnion>
const responses = await multi.exec();
// responses will be: // responses will be:
// [ [Object: null prototype] { name: 'hash2', number: '3' }, 0, '4' ] // [ [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. // Clean up fixtures.
await client.del(['hash1', 'hash2', 'hash3']); await client.del(['hash1', 'hash2', 'hash3']);
client.destroy(); client.close();

View File

@@ -13,9 +13,11 @@ function restrictFunctionCalls(fn, maxCalls) {
const fn = restrictFunctionCalls(transaction, 4); const fn = restrictFunctionCalls(transaction, 4);
const pool = await client.createPool();
async function transaction() { async function transaction() {
try { try {
await client.executeIsolated(async (isolatedClient) => { await pool.execute(async (isolatedClient) => {
await isolatedClient.watch('paymentId:1259'); await isolatedClient.watch('paymentId:1259');
const multi = isolatedClient const multi = isolatedClient
.multi() .multi()