You've already forked node-redis
mirror of
https://github.com/redis/node-redis.git
synced 2025-08-06 02:15:48 +03:00
some cleanups
This commit is contained in:
36
README.md
36
README.md
@@ -11,17 +11,35 @@
|
||||
|
||||
node-redis is a modern, high performance [Redis](https://redis.io) client for Node.js.
|
||||
|
||||
## Installation
|
||||
|
||||
Start a redis-server via docker (or any other method you prefer):
|
||||
|
||||
```bash
|
||||
docker run -p 6379:6379 -it redis/redis-stack-server:latest
|
||||
```
|
||||
|
||||
To install node-redis, simply:
|
||||
|
||||
```bash
|
||||
npm install redis
|
||||
```
|
||||
|
||||
> "redis" is the "whole in one" package that includes all the other packages. If you only need a subset of the commands, you can install the individual packages. See the list below.
|
||||
|
||||
## Packages
|
||||
|
||||
| Name | Description |
|
||||
|----------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| [redis](./packages/redis) | [](https://www.npmjs.com/package/redis) [](https://www.npmjs.com/package/redis) |
|
||||
| [@redis/client](./packages/client) | [](https://www.npmjs.com/package/@redis/client) [](https://www.npmjs.com/package/@redis/client) [](https://redis.js.org/documentation/client/) |
|
||||
| [@redis/bloom](./packages/bloom) | [](https://www.npmjs.com/package/@redis/bloom) [](https://www.npmjs.com/package/@redis/bloom) [](https://redis.js.org/documentation/bloom/) [Redis Bloom](https://oss.redis.com/redisbloom/) commands |
|
||||
| [@redis/graph](./packages/graph) | [](https://www.npmjs.com/package/@redis/graph) [](https://www.npmjs.com/package/@redis/graph) [](https://redis.js.org/documentation/graph/) [Redis Graph](https://oss.redis.com/redisgraph/) commands |
|
||||
| [@redis/json](./packages/json) | [](https://www.npmjs.com/package/@redis/json) [](https://www.npmjs.com/package/@redis/json) [](https://redis.js.org/documentation/json/) [Redis JSON](https://oss.redis.com/redisjson/) commands |
|
||||
| [@redis/search](./packages/search) | [](https://www.npmjs.com/package/@redis/search) [](https://www.npmjs.com/package/@redis/search) [](https://redis.js.org/documentation/search/) [RediSearch](https://oss.redis.com/redisearch/) commands |
|
||||
| [@redis/time-series](./packages/time-series) | [](https://www.npmjs.com/package/@redis/time-series) [](https://www.npmjs.com/package/@redis/time-series) [](https://redis.js.org/documentation/time-series/) [Redis Time-Series](https://oss.redis.com/redistimeseries/) commands |
|
||||
| Name | Description |
|
||||
|------------------------------------------------|---------------------------------------------------------------------------------------------|
|
||||
| [`redis`](./packages/redis) | The client with all the ["redis-stack"](https://github.com/redis-stack/redis-stack) modules |
|
||||
| [`@redis/client`](./packages/client) | The base clients (i.e `RedisClient`, `RedisCluster`, etc.) |
|
||||
| [`@redis/bloom`](./packages/bloom) | [Redis Bloom](https://redis.io/docs/data-types/probabilistic/) commands |
|
||||
| [`redis/graph`](./packages/graph) | [Redis Graph](https://redis.io/docs/data-types/probabilistic/) commands |
|
||||
| [`@redis/json`](./packages/json) | [Redis JSON](https://redis.io/docs/data-types/json/) commands |
|
||||
| [`@redis/search`](./packages/search) | [RediSearch](https://redis.io/docs/interact/search-and-query/) commands |
|
||||
| [`@redis/time-series`](./packages/time-series) | [Redis Time-Series](https://redis.io/docs/data-types/timeseries/) commands |
|
||||
|
||||
> Looking for a high-level library to handle object mapping? See [redis-om-node](https://github.com/redis/redis-om-node)!
|
||||
|
||||
## Contributing
|
||||
|
||||
|
1538
package-lock.json
generated
1538
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
16
package.json
16
package.json
@@ -6,22 +6,20 @@
|
||||
],
|
||||
"scripts": {
|
||||
"test": "npm run test -ws --if-present",
|
||||
"build": "NODE_OPTIONS='--max-old-space-size=4096' tsc --build",
|
||||
"build": "tsc --build",
|
||||
"documentation": "typedoc",
|
||||
"gh-pages": "gh-pages -d ./documentation -e ./documentation -u 'documentation-bot <documentation@bot>'"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@istanbuljs/nyc-config-typescript": "^1.0.2",
|
||||
"@types/mocha": "^10.0.6",
|
||||
"@types/node": "^20.10.3",
|
||||
"@typescript-eslint/eslint-plugin": "^6.13.2",
|
||||
"@typescript-eslint/parser": "^6.13.2",
|
||||
"gh-pages": "^6.1.0",
|
||||
"@types/node": "^20.11.16",
|
||||
"gh-pages": "^6.1.1",
|
||||
"mocha": "^10.2.0",
|
||||
"nyc": "^15.1.0",
|
||||
"release-it": "^17.0.0",
|
||||
"tsx": "^4.6.2",
|
||||
"typedoc": "^0.25.4",
|
||||
"typescript": "^5.3.2"
|
||||
"release-it": "^17.0.3",
|
||||
"tsx": "^4.7.0",
|
||||
"typedoc": "^0.25.7",
|
||||
"typescript": "^5.3.3"
|
||||
}
|
||||
}
|
||||
|
@@ -1,14 +1,17 @@
|
||||
# @redis/bloom
|
||||
|
||||
This package provides support for the [RedisBloom](https://redisbloom.io) module, which adds additional probabilistic data structures to Redis. It extends the [Node Redis client](https://github.com/redis/node-redis) to include functions for each of the RediBloom commands.
|
||||
This package provides support for the [RedisBloom](https://redis.io/docs/data-types/probabilistic/) module, which adds additional probabilistic data structures to Redis.
|
||||
|
||||
To use these extra commands, your Redis server must have the RedisBloom module installed.
|
||||
Should be used with [`redis`/`@redis/client`](https://github.com/redis/node-redis).
|
||||
|
||||
:warning: To use these extra commands, your Redis server must have the RedisBloom module installed.
|
||||
|
||||
RedisBloom provides the following probabilistic data structures:
|
||||
|
||||
* Bloom Filter: for checking set membership with a high degree of certainty.
|
||||
* Cuckoo Filter: for checking set membership with a high degree of certainty.
|
||||
* Count-Min Sketch: Determine the frequency of events in a stream.
|
||||
* T-Digest: for estimating the quantiles of a stream of data.
|
||||
* Top-K: Maintain a list of k most frequently seen items.
|
||||
* Count-Min Sketch: Determine the frequency of events in a stream.
|
||||
|
||||
For complete examples, see `bloom-filter.js`, `cuckoo-filter.js`, `count-min-sketch.js` and `topk.js` in the Node Redis examples folder.
|
||||
For some examples, see [`bloom-filter.js`](https://github.com/redis/node-redis/tree/master/examples/bloom-filter.js), [`cuckoo-filter.js`](https://github.com/redis/node-redis/tree/master/examples/cuckoo-filter.js), [`count-min-sketch.js`](https://github.com/redis/node-redis/tree/master/examples/count-min-sketch.js) and [`topk.js`](https://github.com/redis/node-redis/tree/master/examples/topk.js) in the [examples folder](https://github.com/redis/node-redis/tree/master/examples).
|
||||
|
@@ -17,6 +17,9 @@
|
||||
"devDependencies": {
|
||||
"@redis/test-utils": "*"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/redis/node-redis.git"
|
||||
|
@@ -17,8 +17,7 @@ export { RedisClusterType, RedisClusterOptions };
|
||||
export const createCluster = RedisCluster.create;
|
||||
|
||||
import RedisSentinel from './lib/sentinel';
|
||||
import { RedisSentinelOptions, RedisSentinelType } from './lib/sentinel/types';
|
||||
export { RedisSentinelType, RedisSentinelOptions };
|
||||
export { RedisSentinelOptions, RedisSentinelType } from './lib/sentinel/types';
|
||||
export const createSentinel = RedisSentinel.create;
|
||||
|
||||
// export { GeoReplyWith } from './lib/commands/generic-transformers';
|
||||
|
@@ -460,7 +460,9 @@ export default class RedisClient<
|
||||
})
|
||||
.on('reconnecting', () => this.emit('reconnecting'))
|
||||
.on('drain', () => this.#maybeScheduleWrite())
|
||||
.on('end', () => this.emit('end'));
|
||||
.on('end', () => {
|
||||
console.log('socket on end, emitting end', this.emit('end'));
|
||||
});
|
||||
}
|
||||
|
||||
#pingTimer?: NodeJS.Timeout;
|
||||
|
@@ -88,7 +88,7 @@ async function steadyState(frame: SentinelFramework) {
|
||||
}
|
||||
|
||||
["redis-sentinel-test-password", undefined].forEach(function (password) {
|
||||
describe.only(`Sentinel - password = ${password}`, () => {
|
||||
describe.skip(`Sentinel - password = ${password}`, () => {
|
||||
const config: RedisSentinelConfig = { sentinelName: "test", numberOfNodes: 3, password: password };
|
||||
const frame = new SentinelFramework(config);
|
||||
let tracer = new Array<string>();
|
||||
|
@@ -1,4 +1,5 @@
|
||||
import { RedisModules } from '@redis/client';
|
||||
|
||||
import { RedisModules } from '../RESP/types';
|
||||
import sentinel from './commands';
|
||||
|
||||
export default {
|
||||
|
@@ -16,11 +16,11 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@redis/test-utils": "*",
|
||||
"@types/sinon": "^17.0.2",
|
||||
"@types/sinon": "^17.0.3",
|
||||
"sinon": "^17.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
"node": ">= 18"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
@@ -1,51 +0,0 @@
|
||||
import { RedisArgument, TuplesToMapReply, BlobStringReply, ArrayReply, NullReply, SetReply, UnwrapReply, Resp2Reply, CommandArguments, Command, ReplyWithTypeMapping } from '../RESP/types';
|
||||
|
||||
export interface TFunctionListOptions {
|
||||
LIBRARYNAME?: RedisArgument;
|
||||
}
|
||||
|
||||
export type TFunctionListReplyItem = [
|
||||
[BlobStringReply<'library_name'>, BlobStringReply | NullReply],
|
||||
[BlobStringReply<'engine'>, BlobStringReply],
|
||||
[BlobStringReply<'functions'>, ArrayReply<TuplesToMapReply<[
|
||||
[BlobStringReply<'name'>, BlobStringReply],
|
||||
[BlobStringReply<'description'>, BlobStringReply | NullReply],
|
||||
[BlobStringReply<'flags'>, SetReply<BlobStringReply>],
|
||||
]>>]
|
||||
];
|
||||
|
||||
export type TFunctionListReply = ArrayReply<TuplesToMapReply<TFunctionListReplyItem>>;
|
||||
|
||||
export default {
|
||||
FIRST_KEY_INDEX: undefined,
|
||||
IS_READ_ONLY: false,
|
||||
transformArguments(options?: TFunctionListOptions) {
|
||||
const args: CommandArguments = ['FUNCTION', 'LIST'];
|
||||
|
||||
if (options?.LIBRARYNAME) {
|
||||
args.push('LIBRARYNAME', options.LIBRARYNAME);
|
||||
}
|
||||
|
||||
return args;
|
||||
},
|
||||
transformReply: {
|
||||
2: (reply: UnwrapReply<Resp2Reply<TFunctionListReply>>) => {
|
||||
return reply.map(library => {
|
||||
const unwrapped = library as unknown as UnwrapReply<typeof library>;
|
||||
return {
|
||||
library_name: unwrapped[1],
|
||||
engine: unwrapped[3],
|
||||
functions: (unwrapped[5] as unknown as UnwrapReply<typeof unwrapped[5]>).map(fn => {
|
||||
const unwrapped = fn as unknown as UnwrapReply<typeof fn>;
|
||||
return {
|
||||
name: unwrapped[1],
|
||||
description: unwrapped[3],
|
||||
flags: unwrapped[5]
|
||||
};
|
||||
})
|
||||
};
|
||||
});
|
||||
},
|
||||
3: undefined as unknown as () => TFunctionListReply
|
||||
}
|
||||
} as const satisfies Command;
|
@@ -17,6 +17,9 @@
|
||||
"devDependencies": {
|
||||
"@redis/test-utils": "*"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/redis/node-redis.git"
|
||||
|
@@ -1,12 +1,14 @@
|
||||
# @redis/json
|
||||
|
||||
This package provides support for the [RedisJSON](https://redis.io/docs/stack/json/) 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.
|
||||
This package provides support for the [RedisJSON](https://redis.io/docs/data-types/json/) module, which adds JSON as a native data type to Redis.
|
||||
|
||||
To use these extra commands, your Redis server must have the RedisJSON module installed.
|
||||
Should be used with [`redis`/`@redis/client`](https://github.com/redis/node-redis).
|
||||
|
||||
:warning: To use these extra commands, your Redis server must have the RedisJSON module installed.
|
||||
|
||||
## Usage
|
||||
|
||||
For a complete example, see [`managing-json.js`](https://github.com/redis/node-redis/blob/master/examples/managing-json.js) in the Node Redis examples folder.
|
||||
For a complete example, see [`managing-json.js`](https://github.com/redis/node-redis/blob/master/examples/managing-json.js) in the [examples folder](https://github.com/redis/node-redis/tree/master/examples).
|
||||
|
||||
### Storing JSON Documents in Redis
|
||||
|
||||
@@ -15,33 +17,27 @@ The [`JSON.SET`](https://redis.io/commands/json.set/) command stores a JSON valu
|
||||
Here, we'll store a JSON document in the root of the Redis key "`mydoc`":
|
||||
|
||||
```javascript
|
||||
import { createClient } from 'redis';
|
||||
|
||||
...
|
||||
await client.json.set('noderedis:jsondata', '$', {
|
||||
name: 'Roberta McDonald',
|
||||
pets: [
|
||||
{
|
||||
pets: [{
|
||||
name: 'Rex',
|
||||
species: 'dog',
|
||||
age: 3,
|
||||
isMammal: true
|
||||
},
|
||||
{
|
||||
}, {
|
||||
name: 'Goldie',
|
||||
species: 'fish',
|
||||
age: 2,
|
||||
isMammal: false
|
||||
}
|
||||
]
|
||||
}]
|
||||
});
|
||||
```
|
||||
|
||||
For more information about RedisJSON's path syntax, [check out the documentation](https://redis.io/docs/stack/json/path/).
|
||||
For more information about RedisJSON's path syntax, [check out the documentation](https://redis.io/docs/data-types/json/path/).
|
||||
|
||||
### Retrieving JSON Documents from Redis
|
||||
|
||||
With RedisJSON, we can retrieve all or part(s) of a JSON document using the [`JSON.GET`](https://redis.io/commands/json.get/) command and one or more JSON Paths. Let's get the name and age of one of the pets:
|
||||
With RedisJSON, we can retrieve all or part(s) of a JSON document using the [`JSON.GET`](https://redis.io/commands/json.get/) command and one or more JSON Paths. Let's get the name and age of one of the pets:
|
||||
|
||||
```javascript
|
||||
const results = await client.json.get('noderedis:jsondata', {
|
||||
|
@@ -17,6 +17,9 @@
|
||||
"devDependencies": {
|
||||
"@redis/test-utils": "*"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/redis/node-redis.git"
|
||||
|
@@ -1,32 +1,5 @@
|
||||
# Node-Redis
|
||||
|
||||
[](https://github.com/redis/node-redis/actions/workflows/tests.yml)
|
||||
[](https://codecov.io/gh/redis/node-redis)
|
||||
[](https://github.com/redis/node-redis/blob/master/LICENSE)
|
||||
|
||||
[](https://discord.gg/redis)
|
||||
[](https://www.twitch.tv/redisinc)
|
||||
[](https://www.youtube.com/redisinc)
|
||||
[](https://twitter.com/redisinc)
|
||||
|
||||
node-redis is a modern, high performance [Redis](https://redis.io) client for Node.js.
|
||||
|
||||
## Installation
|
||||
|
||||
Start a redis via docker:
|
||||
|
||||
``` bash
|
||||
docker run -p 6379:6379 -it redis/redis-stack-server:latest
|
||||
```
|
||||
|
||||
To install node-redis, simply:
|
||||
|
||||
```bash
|
||||
npm install redis
|
||||
```
|
||||
|
||||
Looking for a high-level library to handle object mapping? See [redis-om-node](https://github.com/redis/redis-om-node)!
|
||||
|
||||
## Usage
|
||||
|
||||
### Basic Example
|
||||
@@ -43,7 +16,7 @@ const value = await client.get('key');
|
||||
await client.close();
|
||||
```
|
||||
|
||||
> :warning: You **MUST** listen to `error` events. If a client doesn't have at least one `error` listener registered and an `error` occurs, that error will be thrown and the Node.js process will exit. See the [`EventEmitter` docs](https://nodejs.org/api/events.html#events_error_events) for more details.
|
||||
> :warning: You **MUST** listen to `error` events. If a client doesn't have at least one `error` listener registered and an `error` occurs, that error will be thrown and the Node.js process will exit. See the [`EventEmitter` docs](https://nodejs.org/api/events.html#error-events) for more details.
|
||||
|
||||
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]`:
|
||||
|
||||
@@ -55,6 +28,8 @@ createClient({
|
||||
|
||||
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).
|
||||
|
||||
### Connection State
|
||||
|
||||
To client exposes 2 `boolean`s that track the client state:
|
||||
1. `isOpen` - the client is either connecting or connected.
|
||||
2. `isReady` - the client is connected and ready to send
|
||||
@@ -175,7 +150,7 @@ await Promise.all([
|
||||
|
||||
### Events
|
||||
|
||||
The Node Redis client class is an Nodejs EventEmitter and it emits an event each time the network status changes:
|
||||
The client extends `EventEmitter` and emits the following events:
|
||||
|
||||
| Name | When | Listener arguments |
|
||||
|-------------------------|------------------------------------------------------------------------------------|------------------------------------------------------------|
|
||||
@@ -186,11 +161,9 @@ The Node Redis client class is an Nodejs EventEmitter and it emits an event each
|
||||
| `reconnecting` | Client is trying to reconnect to the server | *No arguments* |
|
||||
| `sharded-channel-moved` | See [here](../../docs/pub-sub.md#sharded-channel-moved-event) | See [here](../../docs/pub-sub.md#sharded-channel-moved-event) |
|
||||
|
||||
> :warning: You **MUST** listen to `error` events. If a client doesn't have at least one `error` listener registered and an `error` occurs, that error will be thrown and the Node.js process will exit. See the [`EventEmitter` docs](https://nodejs.org/api/events.html#events_error_events) for more details.
|
||||
> :warning: You **MUST** listen to `error` events. If a client doesn't have at least one `error` listener registered and an `error` occurs, that error will be thrown and the Node.js process will exit. See the [`EventEmitter` docs](https://nodejs.org/api/events.html#error-events) for more details.
|
||||
|
||||
> The client will not emit [any other events](../../docs/v3-to-v4.md#all-the-removed-events) beyond those listed above.
|
||||
|
||||
### Links
|
||||
### Read more
|
||||
|
||||
- [Transactions (`MULTI`/`EXEC`)](../../docs/transactions.md).
|
||||
- [Pub/Sub](../../docs/pub-sub.md).
|
||||
@@ -200,6 +173,7 @@ The Node Redis client class is an Nodejs EventEmitter and it emits an event each
|
||||
- [Pool](../../docs/pool.md).
|
||||
- [Clustering](../../docs/clustering.md).
|
||||
- [Sentinel](../../docs/sentinel.md).
|
||||
- [FAQ](../../docs/FAQ.md).
|
||||
|
||||
## Supported Redis versions
|
||||
|
||||
|
@@ -17,6 +17,9 @@
|
||||
"@redis/search": "2.0.0-next.2",
|
||||
"@redis/time-series": "2.0.0-next.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/redis/node-redis.git"
|
||||
|
@@ -1,18 +1,20 @@
|
||||
# @redis/search
|
||||
|
||||
This package provides support for the [RediSearch](https://redisearch.io) module, which adds indexing and querying support for data stored in Redis Hashes or as JSON documents with the RedisJSON module. It extends the [Node Redis client](https://github.com/redis/node-redis) to include functions for each of the RediSearch commands.
|
||||
This package provides support for the [RediSearch](https://redis.io/docs/interact/search-and-query/) module, which adds indexing and querying support for data stored in Redis Hashes or as JSON documents with the [RedisJSON](https://redis.io/docs/data-types/json/) module.
|
||||
|
||||
To use these extra commands, your Redis server must have the RediSearch module installed. To index and query JSON documents, you'll also need to add the RedisJSON module.
|
||||
Should be used with [`redis`/`@redis/client`](https://github.com/redis/node-redis).
|
||||
|
||||
:warning: To use these extra commands, your Redis server must have the RediSearch module installed. To index and query JSON documents, you'll also need to add the RedisJSON module.
|
||||
|
||||
## Usage
|
||||
|
||||
For complete examples, see [`search-hashes.js`](https://github.com/redis/node-redis/blob/master/examples/search-hashes.js) and [`search-json.js`](https://github.com/redis/node-redis/blob/master/examples/search-json.js) in the Node Redis examples folder.
|
||||
For complete examples, see [`search-hashes.js`](https://github.com/redis/node-redis/blob/master/examples/search-hashes.js) and [`search-json.js`](https://github.com/redis/node-redis/blob/master/examples/search-json.js) in the [examples folder](https://github.com/redis/node-redis/tree/master/examples).
|
||||
|
||||
### Indexing and Querying Data in Redis Hashes
|
||||
|
||||
#### Creating an Index
|
||||
|
||||
Before we can perform any searches, we need to tell RediSearch how to index our data, and which Redis keys to find that data in. The [FT.CREATE](https://redis.io/commands/ft.create) command creates a RediSearch index. Here's how to use it to create an index we'll call `idx:animals` where we want to index hashes containing `name`, `species` and `age` fields, and whose key names in Redis begin with the prefix `noderedis:animals`:
|
||||
Before we can perform any searches, we need to tell RediSearch how to index our data, and which Redis keys to find that data in. The [FT.CREATE](https://redis.io/commands/ft.create) command creates a RediSearch index. Here's how to use it to create an index we'll call `idx:animals` where we want to index hashes containing `name`, `species` and `age` fields, and whose key names in Redis begin with the prefix `noderedis:animals`:
|
||||
|
||||
```javascript
|
||||
await client.ft.create('idx:animals', {
|
||||
|
@@ -17,6 +17,9 @@
|
||||
"devDependencies": {
|
||||
"@redis/test-utils": "*"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/redis/node-redis.git"
|
||||
|
@@ -1,8 +1,10 @@
|
||||
# @redis/time-series
|
||||
|
||||
This package provides support for the [RedisTimeSeries](https://redistimeseries.io) module, which adds a time series data structure to Redis. It extends the [Node Redis client](https://github.com/redis/node-redis) to include functions for each of the RedisTimeSeries commands.
|
||||
This package provides support for the [RedisTimeSeries](https://redis.io/docs/data-types/timeseries/) module, which adds a time series data structure to Redis.
|
||||
|
||||
To use these extra commands, your Redis server must have the RedisTimeSeries module installed.
|
||||
Should be used with [`redis`/`@redis/client`](https://github.com/redis/node-redis).
|
||||
|
||||
:warning: To use these extra commands, your Redis server must have the RedisTimeSeries module installed.
|
||||
|
||||
## Usage
|
||||
|
||||
@@ -20,20 +22,18 @@ import { createClient } from 'redis';
|
||||
import { TimeSeriesDuplicatePolicies, TimeSeriesEncoding, TimeSeriesAggregationType } from '@redis/time-series';
|
||||
|
||||
...
|
||||
const created = await client.ts.create('temperature', {
|
||||
RETENTION: 86400000, // 1 day in milliseconds
|
||||
ENCODING: TimeSeriesEncoding.UNCOMPRESSED, // No compression - When not specified, the option is set to COMPRESSED
|
||||
DUPLICATE_POLICY: TimeSeriesDuplicatePolicies.BLOCK, // No duplicates - When not specified: set to the global DUPLICATE_POLICY configuration of the database (which by default, is BLOCK).
|
||||
});
|
||||
|
||||
const created = await client.ts.create('temperature', {
|
||||
RETENTION: 86400000, // 1 day in milliseconds
|
||||
ENCODING: TimeSeriesEncoding.UNCOMPRESSED, // No compression - When not specified, the option is set to COMPRESSED
|
||||
DUPLICATE_POLICY: TimeSeriesDuplicatePolicies.BLOCK, // No duplicates - When not specified: set to the global DUPLICATE_POLICY configuration of the database (which by default, is BLOCK).
|
||||
});
|
||||
|
||||
if (created === 'OK') {
|
||||
console.log('Created timeseries.');
|
||||
} else {
|
||||
console.log('Error creating timeseries :(');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (created === 'OK') {
|
||||
console.log('Created timeseries.');
|
||||
} else {
|
||||
console.log('Error creating timeseries :(');
|
||||
process.exit(1);
|
||||
}
|
||||
```
|
||||
|
||||
### Adding new value to a Time Series data structure in Redis
|
||||
@@ -43,33 +43,31 @@ With RedisTimeSeries, we can add a single value to time series data structure us
|
||||
```javascript
|
||||
|
||||
let value = Math.floor(Math.random() * 1000) + 1; // Random data point value
|
||||
let currentTimestamp = 1640995200000; // Jan 1 2022 00:00:00
|
||||
let num = 0;
|
||||
let currentTimestamp = 1640995200000; // Jan 1 2022 00:00:00
|
||||
let num = 0;
|
||||
|
||||
while (num < 10000) {
|
||||
// Add a new value to the timeseries, providing our own timestamp:
|
||||
// https://redis.io/commands/ts.add/
|
||||
await client.ts.add('temperature', currentTimestamp, value);
|
||||
console.log(`Added timestamp ${currentTimestamp}, value ${value}.`);
|
||||
|
||||
num += 1;
|
||||
value = Math.floor(Math.random() * 1000) + 1; // Get another random value
|
||||
currentTimestamp += 1000; // Move on one second.
|
||||
}
|
||||
|
||||
// Add multiple values to the timeseries in round trip to the server:
|
||||
// https://redis.io/commands/ts.madd/
|
||||
const response = await client.ts.mAdd([{
|
||||
key: 'temperature',
|
||||
timestamp: currentTimestamp + 60000,
|
||||
value: Math.floor(Math.random() * 1000) + 1
|
||||
}, {
|
||||
key: 'temperature',
|
||||
timestamp: currentTimestamp + 120000,
|
||||
value: Math.floor(Math.random() * 1000) + 1
|
||||
}]);
|
||||
while (num < 10000) {
|
||||
// Add a new value to the timeseries, providing our own timestamp:
|
||||
// https://redis.io/commands/ts.add/
|
||||
await client.ts.add('temperature', currentTimestamp, value);
|
||||
console.log(`Added timestamp ${currentTimestamp}, value ${value}.`);
|
||||
|
||||
num += 1;
|
||||
value = Math.floor(Math.random() * 1000) + 1; // Get another random value
|
||||
currentTimestamp += 1000; // Move on one second.
|
||||
}
|
||||
|
||||
// Add multiple values to the timeseries in round trip to the server:
|
||||
// https://redis.io/commands/ts.madd/
|
||||
const response = await client.ts.mAdd([{
|
||||
key: 'temperature',
|
||||
timestamp: currentTimestamp + 60000,
|
||||
value: Math.floor(Math.random() * 1000) + 1
|
||||
}, {
|
||||
key: 'temperature',
|
||||
timestamp: currentTimestamp + 120000,
|
||||
value: Math.floor(Math.random() * 1000) + 1
|
||||
}]);
|
||||
```
|
||||
|
||||
### Retrieving Time Series data from Redis
|
||||
@@ -77,31 +75,29 @@ let value = Math.floor(Math.random() * 1000) + 1; // Random data point value
|
||||
With RedisTimeSeries, we can retrieve the time series data using the [`TS.RANGE`](https://redis.io/commands/ts.range/) command by passing the criteria as follows:
|
||||
|
||||
```javascript
|
||||
|
||||
// Query the timeseries with TS.RANGE:
|
||||
// https://redis.io/commands/ts.range/
|
||||
const fromTimestamp = 1640995200000; // Jan 1 2022 00:00:00
|
||||
const toTimestamp = 1640995260000; // Jan 1 2022 00:01:00
|
||||
const rangeResponse = await client.ts.range('temperature', fromTimestamp, toTimestamp, {
|
||||
// Group into 10 second averages.
|
||||
AGGREGATION: {
|
||||
type: TimeSeriesAggregationType.AVERAGE,
|
||||
timeBucket: 10000
|
||||
}
|
||||
});
|
||||
|
||||
console.log('RANGE RESPONSE:');
|
||||
// rangeResponse looks like:
|
||||
// [
|
||||
// { timestamp: 1640995200000, value: 356.8 },
|
||||
// { timestamp: 1640995210000, value: 534.8 },
|
||||
// { timestamp: 1640995220000, value: 481.3 },
|
||||
// { timestamp: 1640995230000, value: 437 },
|
||||
// { timestamp: 1640995240000, value: 507.3 },
|
||||
// { timestamp: 1640995250000, value: 581.2 },
|
||||
// { timestamp: 1640995260000, value: 600 }
|
||||
// ]
|
||||
// https://redis.io/commands/ts.range/
|
||||
const fromTimestamp = 1640995200000; // Jan 1 2022 00:00:00
|
||||
const toTimestamp = 1640995260000; // Jan 1 2022 00:01:00
|
||||
const rangeResponse = await client.ts.range('temperature', fromTimestamp, toTimestamp, {
|
||||
// Group into 10 second averages.
|
||||
AGGREGATION: {
|
||||
type: TimeSeriesAggregationType.AVERAGE,
|
||||
timeBucket: 10000
|
||||
}
|
||||
});
|
||||
|
||||
console.log('RANGE RESPONSE:');
|
||||
// rangeResponse looks like:
|
||||
// [
|
||||
// { timestamp: 1640995200000, value: 356.8 },
|
||||
// { timestamp: 1640995210000, value: 534.8 },
|
||||
// { timestamp: 1640995220000, value: 481.3 },
|
||||
// { timestamp: 1640995230000, value: 437 },
|
||||
// { timestamp: 1640995240000, value: 507.3 },
|
||||
// { timestamp: 1640995250000, value: 581.2 },
|
||||
// { timestamp: 1640995260000, value: 600 }
|
||||
// ]
|
||||
```
|
||||
|
||||
### Altering Time Series data Stored in Redis
|
||||
@@ -111,12 +107,10 @@ RedisTimeSeries includes commands that can update values in a time series data s
|
||||
Using the [`TS.ALTER`](https://redis.io/commands/ts.alter/) command, we can update time series retention like this:
|
||||
|
||||
```javascript
|
||||
|
||||
// https://redis.io/commands/ts.alter/
|
||||
const alterResponse = await client.ts.alter('temperature', {
|
||||
RETENTION: 0 // Keep the entries forever
|
||||
});
|
||||
|
||||
// https://redis.io/commands/ts.alter/
|
||||
const alterResponse = await client.ts.alter('temperature', {
|
||||
RETENTION: 0 // Keep the entries forever
|
||||
});
|
||||
```
|
||||
|
||||
### Retrieving Information about the timeseries Stored in Redis
|
||||
@@ -126,26 +120,24 @@ RedisTimeSeries also includes commands that can help to view the information on
|
||||
Using the [`TS.INFO`](https://redis.io/commands/ts.info/) command, we can view timeseries information like this:
|
||||
|
||||
```javascript
|
||||
// Get some information about the state of the timeseries.
|
||||
// https://redis.io/commands/ts.info/
|
||||
const tsInfo = await client.ts.info('temperature');
|
||||
|
||||
// Get some information about the state of the timeseries.
|
||||
// https://redis.io/commands/ts.info/
|
||||
const tsInfo = await client.ts.info('temperature');
|
||||
|
||||
// tsInfo looks like this:
|
||||
// {
|
||||
// totalSamples: 1440,
|
||||
// memoryUsage: 28904,
|
||||
// firstTimestamp: 1641508920000,
|
||||
// lastTimestamp: 1641595320000,
|
||||
// retentionTime: 86400000,
|
||||
// chunkCount: 7,
|
||||
// chunkSize: 4096,
|
||||
// chunkType: 'uncompressed',
|
||||
// duplicatePolicy: 'block',
|
||||
// labels: [],
|
||||
// sourceKey: null,
|
||||
// rules: []
|
||||
// }
|
||||
|
||||
// tsInfo looks like this:
|
||||
// {
|
||||
// totalSamples: 1440,
|
||||
// memoryUsage: 28904,
|
||||
// firstTimestamp: 1641508920000,
|
||||
// lastTimestamp: 1641595320000,
|
||||
// retentionTime: 86400000,
|
||||
// chunkCount: 7,
|
||||
// chunkSize: 4096,
|
||||
// chunkType: 'uncompressed',
|
||||
// duplicatePolicy: 'block',
|
||||
// labels: [],
|
||||
// sourceKey: null,
|
||||
// rules: []
|
||||
// }
|
||||
```
|
||||
|
||||
|
@@ -17,6 +17,9 @@
|
||||
"devDependencies": {
|
||||
"@redis/test-utils": "*"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/redis/node-redis.git"
|
||||
|
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"lib": ["ES2023"],
|
||||
"module": "CommonJS",
|
||||
"moduleResolution": "Node",
|
||||
"module": "NodeNext",
|
||||
"moduleResolution": "NodeNext",
|
||||
"target": "ES2022",
|
||||
|
||||
"strict": true,
|
||||
@@ -12,7 +12,9 @@
|
||||
"skipLibCheck": true,
|
||||
|
||||
"composite": true,
|
||||
"sourceMap": true,
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"allowJs": true
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user