You've already forked node-redis
mirror of
https://github.com/redis/node-redis.git
synced 2025-08-06 02:15:48 +03:00
update docs
This commit is contained in:
312
.github/README.md
vendored
312
.github/README.md
vendored
@@ -1,312 +0,0 @@
|
|||||||
# Node-Redis
|
|
||||||
|
|
||||||
[](https://codecov.io/gh/redis/node-redis)
|
|
||||||
[](https://codecov.io/gh/redis/node-redis)
|
|
||||||
[](https://codecov.io/gh/redis/node-redis)
|
|
||||||
[](https://discord.gg/XMMVgxUm)
|
|
||||||
|
|
||||||
node-redis is a modern, high performance [Redis](https://redis.io) client for Node.js with built-in support for Redis 6.2 commands and modules including [RediSearch](https://redisearch.io) and [RedisJSON](https://redisjson.io).
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm install redis@next
|
|
||||||
```
|
|
||||||
|
|
||||||
> :warning: The new interface is clean and cool, but if you have an existing codebase, you'll want to read the [migration guide](../docs/v3-to-v4.md).
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
### Basic Example
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
import { createClient } from 'redis';
|
|
||||||
|
|
||||||
(async () => {
|
|
||||||
const client = createClient();
|
|
||||||
|
|
||||||
client.on('error', (err) => console.log('Redis Client Error', err));
|
|
||||||
|
|
||||||
await client.connect();
|
|
||||||
|
|
||||||
await client.set('key', 'value');
|
|
||||||
const value = await client.get('key');
|
|
||||||
})();
|
|
||||||
```
|
|
||||||
|
|
||||||
The above code connects to localhost on port 6379. To connect to a different host or port, use a connection string in the format `redis[s]://[[username][:password]@][host][:port][/db-number]`:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
createClient({
|
|
||||||
url: 'redis://alice:foobared@awesome.redis.server:6380'
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
You can also use discrete parameters, UNIX sockets, and even TLS to connect. Details can be found in the [client configuration guide](../docs/client-configuration.md).
|
|
||||||
|
|
||||||
### Redis Commands
|
|
||||||
|
|
||||||
There is built-in support for all of the [out-of-the-box Redis commands](https://redis.io/commands). They are exposed using the raw Redis command names (`HSET`, `HGETALL`, etc.) and a friendlier camel-cased version (`hSet`, `hGetAll`, etc.):
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
// raw Redis commands
|
|
||||||
await client.HSET('key', 'field', 'value');
|
|
||||||
await client.HGETALL('key');
|
|
||||||
|
|
||||||
// friendly JavaScript commands
|
|
||||||
await client.hSet('key', 'field', 'value');
|
|
||||||
await client.hGetAll('key');
|
|
||||||
```
|
|
||||||
|
|
||||||
Modifiers to commands are specified using a JavaScript object:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
await client.set('key', 'value', {
|
|
||||||
EX: 10,
|
|
||||||
NX: true
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
Replies will be transformed into useful data structures:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
await client.hGetAll('key'); // { field1: 'value1', field2: 'value2' }
|
|
||||||
await client.hVals('key'); // ['value1', 'value2']
|
|
||||||
```
|
|
||||||
|
|
||||||
### Unsupported Redis Commands
|
|
||||||
|
|
||||||
If you want to run commands and/or use arguments that Node Redis doesn't know about (yet!) use `.sendCommand()`:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
await client.sendCommand(['SET', 'key', 'value', 'NX']); // 'OK'
|
|
||||||
|
|
||||||
await client.sendCommand(['HGETALL', 'key']); // ['key1', 'field1', 'key2', 'field2']
|
|
||||||
```
|
|
||||||
|
|
||||||
### Transactions (Multi/Exec)
|
|
||||||
|
|
||||||
Start a [transaction](https://redis.io/topics/transactions) by calling `.multi()`, then chaining your commands. When you're done, call `.exec()` and you'll get an array back with your results:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
await client.set('another-key', 'another-value');
|
|
||||||
|
|
||||||
const [setKeyReply, otherKeyValue] = await client
|
|
||||||
.multi()
|
|
||||||
.set('key', 'value')
|
|
||||||
.get('another-key')
|
|
||||||
.exec(); // ['OK', 'another-value']
|
|
||||||
```
|
|
||||||
|
|
||||||
You can also [watch](https://redis.io/topics/transactions#optimistic-locking-using-check-and-set) keys by calling `.watch()`. Your transaction will abort if any of the watched keys change.
|
|
||||||
|
|
||||||
To dig deeper into transactions, check out the [Isolated Execution Guide](../docs/isolated-execution.md).
|
|
||||||
|
|
||||||
### Blocking Commands
|
|
||||||
|
|
||||||
Any command can be run on a new connection by specifying the `isolated` option. The newly created connection is closed when the command's `Promise` is fulfilled.
|
|
||||||
|
|
||||||
This pattern works especially well for blocking commands—such as `BLPOP` and `BLMOVE`:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
import { commandOptions } from 'redis';
|
|
||||||
|
|
||||||
const blPopPromise = client.blPop(commandOptions({ isolated: true }), 'key', 0);
|
|
||||||
|
|
||||||
await client.lPush('key', ['1', '2']);
|
|
||||||
|
|
||||||
await blPopPromise; // '2'
|
|
||||||
```
|
|
||||||
|
|
||||||
To learn more about isolated execution, check out the [guide](../docs/isolated-execution.md).
|
|
||||||
|
|
||||||
### Pub/Sub
|
|
||||||
|
|
||||||
Subscribing to a channel requires a dedicated stand-alone connection. You can easily get one by `.duplicate()`ing an existing Redis connection.
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
const subscriber = client.duplicate();
|
|
||||||
|
|
||||||
await subscriber.connect();
|
|
||||||
```
|
|
||||||
|
|
||||||
Once you have one, simply subscribe and unsubscribe as needed:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
await subscriber.subscribe('channel', (message) => {
|
|
||||||
console.log(message); // 'message'
|
|
||||||
});
|
|
||||||
|
|
||||||
await subscriber.pSubscribe('channe*', (message, channel) => {
|
|
||||||
console.log(message, channel); // 'message', 'channel'
|
|
||||||
});
|
|
||||||
|
|
||||||
await subscriber.unsubscribe('channel');
|
|
||||||
|
|
||||||
await subscriber.pUnsubscribe('channe*');
|
|
||||||
```
|
|
||||||
|
|
||||||
Publish a message on a channel:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
await publisher.publish('channel', 'message');
|
|
||||||
```
|
|
||||||
|
|
||||||
There is support for buffers as well:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
await subscriber.subscribe('channel', (message) => {
|
|
||||||
console.log(message); // <Buffer 6d 65 73 73 61 67 65>
|
|
||||||
}, true);
|
|
||||||
|
|
||||||
await subscriber.pSubscribe('channe*', (message, channel) => {
|
|
||||||
console.log(message, channel); // <Buffer 6d 65 73 73 61 67 65>, <Buffer 63 68 61 6e 6e 65 6c>
|
|
||||||
}, true);
|
|
||||||
```
|
|
||||||
|
|
||||||
### Scan Iterator
|
|
||||||
|
|
||||||
[`SCAN`](https://redis.io/commands/scan) results can be looped over using [async iterators](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/asyncIterator):
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
for await (const key of client.scanIterator()) {
|
|
||||||
// use the key!
|
|
||||||
await client.get(key);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
This works with `HSCAN`, `SSCAN`, and `ZSCAN` too:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
for await (const { field, value } of client.hScanIterator('hash')) {}
|
|
||||||
for await (const member of client.sScanIterator('set')) {}
|
|
||||||
for await (const { score, member } of client.zScanIterator('sorted-set')) {}
|
|
||||||
```
|
|
||||||
|
|
||||||
You can override the default options by providing a configuration object:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
client.scanIterator({
|
|
||||||
TYPE: 'string', // `SCAN` only
|
|
||||||
MATCH: 'patter*',
|
|
||||||
COUNT: 100
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### Lua Scripts
|
|
||||||
|
|
||||||
Define new functions using [Lua scripts](https://redis.io/commands/eval) which execute on the Redis server:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
import { createClient, defineScript } from 'redis';
|
|
||||||
|
|
||||||
(async () => {
|
|
||||||
const client = createClient({
|
|
||||||
scripts: {
|
|
||||||
add: defineScript({
|
|
||||||
NUMBER_OF_KEYS: 1,
|
|
||||||
SCRIPT:
|
|
||||||
'local val = redis.pcall("GET", KEYS[1]);' +
|
|
||||||
'return val + ARGV[1];',
|
|
||||||
transformArguments(key: string, toAdd: number): Array<string> {
|
|
||||||
return [key, toAdd.toString()];
|
|
||||||
},
|
|
||||||
transformReply(reply: number): number {
|
|
||||||
return reply;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
await client.connect();
|
|
||||||
|
|
||||||
await client.set('key', '1');
|
|
||||||
await client.add('key', 2); // 3
|
|
||||||
})();
|
|
||||||
```
|
|
||||||
|
|
||||||
### Disconnecting
|
|
||||||
|
|
||||||
There are two functions that disconnect a client from the Redis server. In most scenarios you should use `.quit()` to ensure that pending commands are sent to Redis before closing a connection.
|
|
||||||
|
|
||||||
#### `.QUIT()`/`.quit()`
|
|
||||||
|
|
||||||
Gracefully close a client's connection to Redis, by sending the [`QUIT`](https://redis.io/commands/quit) command to the server. Before quitting, the client executes any remaining commands in its queue, and will receive replies from Redis for each of them.
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
const [ping, get, quit] = await Promise.all([
|
|
||||||
client.ping(),
|
|
||||||
client.get('key'),
|
|
||||||
client.quit()
|
|
||||||
]); // ['PONG', null, 'OK']
|
|
||||||
|
|
||||||
try {
|
|
||||||
await client.get('key');
|
|
||||||
} catch (err) {
|
|
||||||
// ClosedClient Error
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### `.disconnect()`
|
|
||||||
|
|
||||||
Forcibly close a client's connection to Redis immediately. Calling `disconnect` will not send further pending commands to the Redis server, or wait for or parse outstanding responses.
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
await client.disconnect();
|
|
||||||
```
|
|
||||||
|
|
||||||
### Auto-Pipelining
|
|
||||||
|
|
||||||
Node Redis will automatically pipeline requests that are made during the same "tick".
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
client.set('Tm9kZSBSZWRpcw==', 'users:1');
|
|
||||||
client.sAdd('users:1:tokens', 'Tm9kZSBSZWRpcw==');
|
|
||||||
```
|
|
||||||
|
|
||||||
Of course, if you don't do something with your Promises you're certain to get [unhandled Promise exceptions](https://nodejs.org/api/process.html#process_event_unhandledrejection). To take advantage of auto-pipelining and handle your Promises, use `Promise.all()`.
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
await Promise.all([
|
|
||||||
client.set('Tm9kZSBSZWRpcw==', 'users:1'),
|
|
||||||
client.sAdd('users:1:tokens', 'Tm9kZSBSZWRpcw==')
|
|
||||||
]);
|
|
||||||
```
|
|
||||||
|
|
||||||
### Clustering
|
|
||||||
|
|
||||||
Check out the [Clustering Guide](../docs/clustering.md) when using Node Redis to connect to a Redis Cluster.
|
|
||||||
|
|
||||||
## Supported Redis versions
|
|
||||||
|
|
||||||
Node Redis is supported with the following versions of Redis:
|
|
||||||
|
|
||||||
| Version | Supported |
|
|
||||||
|---------|--------------------|
|
|
||||||
| 6.2.z | :heavy_check_mark: |
|
|
||||||
| 6.0.z | :heavy_check_mark: |
|
|
||||||
| 5.y.z | :heavy_check_mark: |
|
|
||||||
| < 5.0 | :x: |
|
|
||||||
|
|
||||||
> Node Redis should work with older versions of Redis, but it is not fully tested and we cannot offer support.
|
|
||||||
|
|
||||||
## Packages
|
|
||||||
|
|
||||||
| Name | Description |
|
|
||||||
|-------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
||||||
| [redis](../) | [](https://www.npmjs.com/package/redis/v/next) [](https://www.npmjs.com/package/redis/v/next) |
|
|
||||||
| [@node-redis/client](../packages/client) | [](https://www.npmjs.com/package/@node-redis/client/v/next) [](https://www.npmjs.com/package/@node-redis/client/v/next) |
|
|
||||||
| [@node-redis/json](../packages/json) | [](https://www.npmjs.com/package/@node-redis/json/v/next) [](https://www.npmjs.com/package/@node-redis/json/v/next) [Redis JSON](https://oss.redis.com/redisjson/) commands |
|
|
||||||
| [@node-redis/search](../packages/search) | [](https://www.npmjs.com/package/@node-redis/search/v/next) [](https://www.npmjs.com/package/@node-redis/search/v/next) [Redis Search](https://oss.redis.com/redisearch/) commands |
|
|
||||||
|
|
||||||
## Contributing
|
|
||||||
|
|
||||||
If you'd like to contribute, check out the [contributing guide](CONTRIBUTING.md).
|
|
||||||
|
|
||||||
Thank you to all the people who already contributed to Node Redis!
|
|
||||||
|
|
||||||
[](https://github.com/redis/node-redis/graphs/contributors)
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
This repository is licensed under the "MIT" license. See [LICENSE](LICENSE).
|
|
314
README.md
314
README.md
@@ -1,2 +1,312 @@
|
|||||||
# redis
|
# Node-Redis
|
||||||
The source code and documentation for this package are in the main [node-redis](https://github.com/redis/node-redis) repo.
|
|
||||||
|
[](https://codecov.io/gh/redis/node-redis)
|
||||||
|
[](https://codecov.io/gh/redis/node-redis)
|
||||||
|
[](https://codecov.io/gh/redis/node-redis)
|
||||||
|
[](https://discord.gg/XMMVgxUm)
|
||||||
|
|
||||||
|
node-redis is a modern, high performance [Redis](https://redis.io) client for Node.js with built-in support for Redis 6.2 commands and modules including [RediSearch](https://redisearch.io) and [RedisJSON](https://redisjson.io).
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install redis
|
||||||
|
```
|
||||||
|
|
||||||
|
> :warning: The new interface is clean and cool, but if you have an existing codebase, you'll want to read the [migration guide](./docs/v3-to-v4.md).
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
### Basic Example
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { createClient } from 'redis';
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
const client = createClient();
|
||||||
|
|
||||||
|
client.on('error', (err) => console.log('Redis Client Error', err));
|
||||||
|
|
||||||
|
await client.connect();
|
||||||
|
|
||||||
|
await client.set('key', 'value');
|
||||||
|
const value = await client.get('key');
|
||||||
|
})();
|
||||||
|
```
|
||||||
|
|
||||||
|
The above code connects to localhost on port 6379. To connect to a different host or port, use a connection string in the format `redis[s]://[[username][:password]@][host][:port][/db-number]`:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
createClient({
|
||||||
|
url: 'redis://alice:foobared@awesome.redis.server:6380'
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
You can also use discrete parameters, UNIX sockets, and even TLS to connect. Details can be found in the [client configuration guide](./docs/client-configuration.md).
|
||||||
|
|
||||||
|
### Redis Commands
|
||||||
|
|
||||||
|
There is built-in support for all of the [out-of-the-box Redis commands](https://redis.io/commands). They are exposed using the raw Redis command names (`HSET`, `HGETALL`, etc.) and a friendlier camel-cased version (`hSet`, `hGetAll`, etc.):
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// raw Redis commands
|
||||||
|
await client.HSET('key', 'field', 'value');
|
||||||
|
await client.HGETALL('key');
|
||||||
|
|
||||||
|
// friendly JavaScript commands
|
||||||
|
await client.hSet('key', 'field', 'value');
|
||||||
|
await client.hGetAll('key');
|
||||||
|
```
|
||||||
|
|
||||||
|
Modifiers to commands are specified using a JavaScript object:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
await client.set('key', 'value', {
|
||||||
|
EX: 10,
|
||||||
|
NX: true
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
Replies will be transformed into useful data structures:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
await client.hGetAll('key'); // { field1: 'value1', field2: 'value2' }
|
||||||
|
await client.hVals('key'); // ['value1', 'value2']
|
||||||
|
```
|
||||||
|
|
||||||
|
### Unsupported Redis Commands
|
||||||
|
|
||||||
|
If you want to run commands and/or use arguments that Node Redis doesn't know about (yet!) use `.sendCommand()`:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
await client.sendCommand(['SET', 'key', 'value', 'NX']); // 'OK'
|
||||||
|
|
||||||
|
await client.sendCommand(['HGETALL', 'key']); // ['key1', 'field1', 'key2', 'field2']
|
||||||
|
```
|
||||||
|
|
||||||
|
### Transactions (Multi/Exec)
|
||||||
|
|
||||||
|
Start a [transaction](https://redis.io/topics/transactions) by calling `.multi()`, then chaining your commands. When you're done, call `.exec()` and you'll get an array back with your results:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
await client.set('another-key', 'another-value');
|
||||||
|
|
||||||
|
const [setKeyReply, otherKeyValue] = await client
|
||||||
|
.multi()
|
||||||
|
.set('key', 'value')
|
||||||
|
.get('another-key')
|
||||||
|
.exec(); // ['OK', 'another-value']
|
||||||
|
```
|
||||||
|
|
||||||
|
You can also [watch](https://redis.io/topics/transactions#optimistic-locking-using-check-and-set) keys by calling `.watch()`. Your transaction will abort if any of the watched keys change.
|
||||||
|
|
||||||
|
To dig deeper into transactions, check out the [Isolated Execution Guide](./docs/isolated-execution.md).
|
||||||
|
|
||||||
|
### Blocking Commands
|
||||||
|
|
||||||
|
Any command can be run on a new connection by specifying the `isolated` option. The newly created connection is closed when the command's `Promise` is fulfilled.
|
||||||
|
|
||||||
|
This pattern works especially well for blocking commands—such as `BLPOP` and `BLMOVE`:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { commandOptions } from 'redis';
|
||||||
|
|
||||||
|
const blPopPromise = client.blPop(commandOptions({ isolated: true }), 'key', 0);
|
||||||
|
|
||||||
|
await client.lPush('key', ['1', '2']);
|
||||||
|
|
||||||
|
await blPopPromise; // '2'
|
||||||
|
```
|
||||||
|
|
||||||
|
To learn more about isolated execution, check out the [guide](./docs/isolated-execution.md).
|
||||||
|
|
||||||
|
### Pub/Sub
|
||||||
|
|
||||||
|
Subscribing to a channel requires a dedicated stand-alone connection. You can easily get one by `.duplicate()`ing an existing Redis connection.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
const subscriber = client.duplicate();
|
||||||
|
|
||||||
|
await subscriber.connect();
|
||||||
|
```
|
||||||
|
|
||||||
|
Once you have one, simply subscribe and unsubscribe as needed:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
await subscriber.subscribe('channel', (message) => {
|
||||||
|
console.log(message); // 'message'
|
||||||
|
});
|
||||||
|
|
||||||
|
await subscriber.pSubscribe('channe*', (message, channel) => {
|
||||||
|
console.log(message, channel); // 'message', 'channel'
|
||||||
|
});
|
||||||
|
|
||||||
|
await subscriber.unsubscribe('channel');
|
||||||
|
|
||||||
|
await subscriber.pUnsubscribe('channe*');
|
||||||
|
```
|
||||||
|
|
||||||
|
Publish a message on a channel:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
await publisher.publish('channel', 'message');
|
||||||
|
```
|
||||||
|
|
||||||
|
There is support for buffers as well:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
await subscriber.subscribe('channel', (message) => {
|
||||||
|
console.log(message); // <Buffer 6d 65 73 73 61 67 65>
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
await subscriber.pSubscribe('channe*', (message, channel) => {
|
||||||
|
console.log(message, channel); // <Buffer 6d 65 73 73 61 67 65>, <Buffer 63 68 61 6e 6e 65 6c>
|
||||||
|
}, true);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Scan Iterator
|
||||||
|
|
||||||
|
[`SCAN`](https://redis.io/commands/scan) results can be looped over using [async iterators](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/asyncIterator):
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
for await (const key of client.scanIterator()) {
|
||||||
|
// use the key!
|
||||||
|
await client.get(key);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
This works with `HSCAN`, `SSCAN`, and `ZSCAN` too:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
for await (const { field, value } of client.hScanIterator('hash')) {}
|
||||||
|
for await (const member of client.sScanIterator('set')) {}
|
||||||
|
for await (const { score, member } of client.zScanIterator('sorted-set')) {}
|
||||||
|
```
|
||||||
|
|
||||||
|
You can override the default options by providing a configuration object:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
client.scanIterator({
|
||||||
|
TYPE: 'string', // `SCAN` only
|
||||||
|
MATCH: 'patter*',
|
||||||
|
COUNT: 100
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Lua Scripts
|
||||||
|
|
||||||
|
Define new functions using [Lua scripts](https://redis.io/commands/eval) which execute on the Redis server:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { createClient, defineScript } from 'redis';
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
const client = createClient({
|
||||||
|
scripts: {
|
||||||
|
add: defineScript({
|
||||||
|
NUMBER_OF_KEYS: 1,
|
||||||
|
SCRIPT:
|
||||||
|
'local val = redis.pcall("GET", KEYS[1]);' +
|
||||||
|
'return val + ARGV[1];',
|
||||||
|
transformArguments(key: string, toAdd: number): Array<string> {
|
||||||
|
return [key, toAdd.toString()];
|
||||||
|
},
|
||||||
|
transformReply(reply: number): number {
|
||||||
|
return reply;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
await client.connect();
|
||||||
|
|
||||||
|
await client.set('key', '1');
|
||||||
|
await client.add('key', 2); // 3
|
||||||
|
})();
|
||||||
|
```
|
||||||
|
|
||||||
|
### Disconnecting
|
||||||
|
|
||||||
|
There are two functions that disconnect a client from the Redis server. In most scenarios you should use `.quit()` to ensure that pending commands are sent to Redis before closing a connection.
|
||||||
|
|
||||||
|
#### `.QUIT()`/`.quit()`
|
||||||
|
|
||||||
|
Gracefully close a client's connection to Redis, by sending the [`QUIT`](https://redis.io/commands/quit) command to the server. Before quitting, the client executes any remaining commands in its queue, and will receive replies from Redis for each of them.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
const [ping, get, quit] = await Promise.all([
|
||||||
|
client.ping(),
|
||||||
|
client.get('key'),
|
||||||
|
client.quit()
|
||||||
|
]); // ['PONG', null, 'OK']
|
||||||
|
|
||||||
|
try {
|
||||||
|
await client.get('key');
|
||||||
|
} catch (err) {
|
||||||
|
// ClosedClient Error
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `.disconnect()`
|
||||||
|
|
||||||
|
Forcibly close a client's connection to Redis immediately. Calling `disconnect` will not send further pending commands to the Redis server, or wait for or parse outstanding responses.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
await client.disconnect();
|
||||||
|
```
|
||||||
|
|
||||||
|
### Auto-Pipelining
|
||||||
|
|
||||||
|
Node Redis will automatically pipeline requests that are made during the same "tick".
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
client.set('Tm9kZSBSZWRpcw==', 'users:1');
|
||||||
|
client.sAdd('users:1:tokens', 'Tm9kZSBSZWRpcw==');
|
||||||
|
```
|
||||||
|
|
||||||
|
Of course, if you don't do something with your Promises you're certain to get [unhandled Promise exceptions](https://nodejs.org/api/process.html#process_event_unhandledrejection). To take advantage of auto-pipelining and handle your Promises, use `Promise.all()`.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
await Promise.all([
|
||||||
|
client.set('Tm9kZSBSZWRpcw==', 'users:1'),
|
||||||
|
client.sAdd('users:1:tokens', 'Tm9kZSBSZWRpcw==')
|
||||||
|
]);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Clustering
|
||||||
|
|
||||||
|
Check out the [Clustering Guide](./docs/clustering.md) when using Node Redis to connect to a Redis Cluster.
|
||||||
|
|
||||||
|
## Supported Redis versions
|
||||||
|
|
||||||
|
Node Redis is supported with the following versions of Redis:
|
||||||
|
|
||||||
|
| Version | Supported |
|
||||||
|
|---------|--------------------|
|
||||||
|
| 6.2.z | :heavy_check_mark: |
|
||||||
|
| 6.0.z | :heavy_check_mark: |
|
||||||
|
| 5.y.z | :heavy_check_mark: |
|
||||||
|
| < 5.0 | :x: |
|
||||||
|
|
||||||
|
> Node Redis should work with older versions of Redis, but it is not fully tested and we cannot offer support.
|
||||||
|
|
||||||
|
## Packages
|
||||||
|
|
||||||
|
| Name | Description |
|
||||||
|
|-----------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
|
| [redis](./) | [](https://www.npmjs.com/package/redis/v/next) [](https://www.npmjs.com/package/redis/v/next) |
|
||||||
|
| [@node-redis/client](./packages/client) | [](https://www.npmjs.com/package/@node-redis/client/v/next) [](https://www.npmjs.com/package/@node-redis/client/v/next) |
|
||||||
|
| [@node-redis/json](./packages/json) | [](https://www.npmjs.com/package/@node-redis/json/v/next) [](https://www.npmjs.com/package/@node-redis/json/v/next) [Redis JSON](https://oss.redis.com/redisjson/) commands |
|
||||||
|
| [@node-redis/search](./packages/search) | [](https://www.npmjs.com/package/@node-redis/search/v/next) [](https://www.npmjs.com/package/@node-redis/search/v/next) [Redis Search](https://oss.redis.com/redisearch/) commands |
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
If you'd like to contribute, check out the [contributing guide](CONTRIBUTING.md).
|
||||||
|
|
||||||
|
Thank you to all the people who already contributed to Node Redis!
|
||||||
|
|
||||||
|
[](https://github.com/redis/node-redis/graphs/contributors)
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
This repository is licensed under the "MIT" license. See [LICENSE](LICENSE).
|
||||||
|
@@ -15,11 +15,11 @@
|
|||||||
| username | | ACL username ([see ACL guide](https://redis.io/topics/acl)) |
|
| username | | ACL username ([see ACL guide](https://redis.io/topics/acl)) |
|
||||||
| password | | ACL password or the old "--requirepass" password |
|
| password | | ACL password or the old "--requirepass" password |
|
||||||
| database | | Database number to connect to (see [`SELECT`](https://redis.io/commands/select) command) |
|
| database | | Database number to connect to (see [`SELECT`](https://redis.io/commands/select) command) |
|
||||||
| modules | | Object defining which [Redis Modules](../.github/README.md#packages) to include |
|
| modules | | Object defining which [Redis Modules](../README.md#packages) to include |
|
||||||
| scripts | | Object defining Lua Scripts to use with this client (see [Lua Scripts](../README.md#lua-scripts)) |
|
| scripts | | Object defining Lua Scripts to use with this client (see [Lua Scripts](../README.md#lua-scripts)) |
|
||||||
| commandsQueueMaxLength | | Maximum length of the client's internal command queue |
|
| commandsQueueMaxLength | | Maximum length of the client's internal command queue |
|
||||||
| readonly | `false` | Connect in [`READONLY`](https://redis.io/commands/readonly) mode |
|
| readonly | `false` | Connect in [`READONLY`](https://redis.io/commands/readonly) mode |
|
||||||
| legacyMode | `false` | Maintain some backwards compatibility (see the [Migration Guide](v3-to-v4.md)) |
|
| legacyMode | `false` | Maintain some backwards compatibility (see the [Migration Guide](./v3-to-v4.md)) |
|
||||||
| isolationPoolOptions | | See the [Isolated Execution Guide](./isolated-execution.md) |
|
| isolationPoolOptions | | See the [Isolated Execution Guide](./isolated-execution.md) |
|
||||||
|
|
||||||
## Reconnect Strategy
|
## Reconnect Strategy
|
||||||
|
@@ -38,7 +38,7 @@ import { createCluster } from 'redis';
|
|||||||
| defaults | | The default configuration values for every client in the cluster. Use this for example when specifying an ACL user to connect with |
|
| defaults | | The default configuration values for every client in the cluster. Use this for example when specifying an ACL user to connect with |
|
||||||
| useReplicas | `false` | When `true`, distribute load by executing readonly commands (such as `GET`, `GEOSEARCH`, etc.) across all cluster nodes. When `false`, only use master nodes |
|
| useReplicas | `false` | When `true`, distribute load by executing readonly commands (such as `GET`, `GEOSEARCH`, etc.) across all cluster nodes. When `false`, only use master nodes |
|
||||||
| maxCommandRedirections | `16` | The maximum number of times a command will be redirected due to `MOVED` or `ASK` errors |
|
| maxCommandRedirections | `16` | The maximum number of times a command will be redirected due to `MOVED` or `ASK` errors |
|
||||||
| modules | | Object defining which [Redis Modules](../../README.md#modules) to include |
|
| modules | | Object defining which [Redis Modules](../README.md#modules) to include |
|
||||||
| scripts | | Object defining Lua Scripts to use with this client (see [Lua Scripts](../README.md#lua-scripts)) |
|
| scripts | | Object defining Lua Scripts to use with this client (see [Lua Scripts](../README.md#lua-scripts)) |
|
||||||
|
|
||||||
## Command Routing
|
## Command Routing
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
## v4.0.0
|
## v4.0.0 - 24 Nov, 2021
|
||||||
|
|
||||||
This version is a major change and refactor, adding modern JavaScript capabilities and multiple breaking changes. See the [migration guide](../../docs/v3-to-v4.md) for tips on how to upgrade.
|
This version is a major change and refactor, adding modern JavaScript capabilities and multiple breaking changes. See the [migration guide](../../docs/v3-to-v4.md) for tips on how to upgrade.
|
||||||
|
|
||||||
@@ -17,10 +17,10 @@ This version is a major change and refactor, adding modern JavaScript capabiliti
|
|||||||
|
|
||||||
- Added support for Promises
|
- Added support for Promises
|
||||||
- Added built-in TypeScript declaration files enabling code completion
|
- Added built-in TypeScript declaration files enabling code completion
|
||||||
- Added support for [clustering](../../.github/README.md#cluster)
|
- Added support for [clustering](../../README.md#cluster)
|
||||||
- Added idiomatic arguments and responses to [Redis commands](../../.github/README.md#redis-commands)
|
- Added idiomatic arguments and responses to [Redis commands](../../README.md#redis-commands)
|
||||||
- Added full support for [Lua Scripts](../../.github/README.md#lua-scripts)
|
- Added full support for [Lua Scripts](../../README.md#lua-scripts)
|
||||||
- Added support for [SCAN iterators](../../.github/README.md#scan-iterator)
|
- Added support for [SCAN iterators](../../README.md#scan-iterator)
|
||||||
- Added the ability to extend Node Redis with Redis Module commands
|
- Added the ability to extend Node Redis with Redis Module commands
|
||||||
|
|
||||||
## v3.1.2
|
## v3.1.2
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
# @node-redis/json
|
# @node-redis/json
|
||||||
|
|
||||||
This package provides support for the [RedisJSON](https://redisjson.io) module, which adds JSON as a native data type to Redis. It extends the [Node Redis client](https://) to include functions for each of the RedisJSON commands.
|
This package provides support for the [RedisJSON](https://redisjson.io) module, which adds JSON as a native data type to Redis. It extends the [Node Redis client](https://github.com/redis/node-redis) to include functions for each of the RedisJSON commands.
|
||||||
|
|
||||||
To use these extra commands, your Redis server must have the RedisJSON module installed.
|
To use these extra commands, your Redis server must have the RedisJSON module installed.
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user