1
0
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:
Leibale
2024-02-05 11:18:27 -05:00
parent 8f3a276509
commit 8340a9e830
21 changed files with 593 additions and 1341 deletions

View File

@@ -11,17 +11,35 @@
node-redis is a modern, high performance [Redis](https://redis.io) client for Node.js. 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 ## Packages
| Name | Description | | Name | Description |
|----------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |------------------------------------------------|---------------------------------------------------------------------------------------------|
| [redis](./packages/redis) | [![Downloads](https://img.shields.io/npm/dm/redis.svg)](https://www.npmjs.com/package/redis) [![Version](https://img.shields.io/npm/v/redis.svg)](https://www.npmjs.com/package/redis) | | [`redis`](./packages/redis) | The client with all the ["redis-stack"](https://github.com/redis-stack/redis-stack) modules |
| [@redis/client](./packages/client) | [![Downloads](https://img.shields.io/npm/dm/@redis/client.svg)](https://www.npmjs.com/package/@redis/client) [![Version](https://img.shields.io/npm/v/@redis/client.svg)](https://www.npmjs.com/package/@redis/client) [![Docs](https://img.shields.io/badge/-documentation-dc382c)](https://redis.js.org/documentation/client/) | | [`@redis/client`](./packages/client) | The base clients (i.e `RedisClient`, `RedisCluster`, etc.) |
| [@redis/bloom](./packages/bloom) | [![Downloads](https://img.shields.io/npm/dm/@redis/bloom.svg)](https://www.npmjs.com/package/@redis/bloom) [![Version](https://img.shields.io/npm/v/@redis/bloom.svg)](https://www.npmjs.com/package/@redis/bloom) [![Docs](https://img.shields.io/badge/-documentation-dc382c)](https://redis.js.org/documentation/bloom/) [Redis Bloom](https://oss.redis.com/redisbloom/) commands | | [`@redis/bloom`](./packages/bloom) | [Redis Bloom](https://redis.io/docs/data-types/probabilistic/) commands |
| [@redis/graph](./packages/graph) | [![Downloads](https://img.shields.io/npm/dm/@redis/graph.svg)](https://www.npmjs.com/package/@redis/graph) [![Version](https://img.shields.io/npm/v/@redis/graph.svg)](https://www.npmjs.com/package/@redis/graph) [![Docs](https://img.shields.io/badge/-documentation-dc382c)](https://redis.js.org/documentation/graph/) [Redis Graph](https://oss.redis.com/redisgraph/) commands | | [`redis/graph`](./packages/graph) | [Redis Graph](https://redis.io/docs/data-types/probabilistic/) commands |
| [@redis/json](./packages/json) | [![Downloads](https://img.shields.io/npm/dm/@redis/json.svg)](https://www.npmjs.com/package/@redis/json) [![Version](https://img.shields.io/npm/v/@redis/json.svg)](https://www.npmjs.com/package/@redis/json) [![Docs](https://img.shields.io/badge/-documentation-dc382c)](https://redis.js.org/documentation/json/) [Redis JSON](https://oss.redis.com/redisjson/) commands | | [`@redis/json`](./packages/json) | [Redis JSON](https://redis.io/docs/data-types/json/) commands |
| [@redis/search](./packages/search) | [![Downloads](https://img.shields.io/npm/dm/@redis/search.svg)](https://www.npmjs.com/package/@redis/search) [![Version](https://img.shields.io/npm/v/@redis/search.svg)](https://www.npmjs.com/package/@redis/search) [![Docs](https://img.shields.io/badge/-documentation-dc382c)](https://redis.js.org/documentation/search/) [RediSearch](https://oss.redis.com/redisearch/) commands | | [`@redis/search`](./packages/search) | [RediSearch](https://redis.io/docs/interact/search-and-query/) commands |
| [@redis/time-series](./packages/time-series) | [![Downloads](https://img.shields.io/npm/dm/@redis/time-series.svg)](https://www.npmjs.com/package/@redis/time-series) [![Version](https://img.shields.io/npm/v/@redis/time-series.svg)](https://www.npmjs.com/package/@redis/time-series) [![Docs](https://img.shields.io/badge/-documentation-dc382c)](https://redis.js.org/documentation/time-series/) [Redis Time-Series](https://oss.redis.com/redistimeseries/) 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 ## Contributing

1538
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -6,22 +6,20 @@
], ],
"scripts": { "scripts": {
"test": "npm run test -ws --if-present", "test": "npm run test -ws --if-present",
"build": "NODE_OPTIONS='--max-old-space-size=4096' tsc --build", "build": "tsc --build",
"documentation": "typedoc", "documentation": "typedoc",
"gh-pages": "gh-pages -d ./documentation -e ./documentation -u 'documentation-bot <documentation@bot>'" "gh-pages": "gh-pages -d ./documentation -e ./documentation -u 'documentation-bot <documentation@bot>'"
}, },
"devDependencies": { "devDependencies": {
"@istanbuljs/nyc-config-typescript": "^1.0.2", "@istanbuljs/nyc-config-typescript": "^1.0.2",
"@types/mocha": "^10.0.6", "@types/mocha": "^10.0.6",
"@types/node": "^20.10.3", "@types/node": "^20.11.16",
"@typescript-eslint/eslint-plugin": "^6.13.2", "gh-pages": "^6.1.1",
"@typescript-eslint/parser": "^6.13.2",
"gh-pages": "^6.1.0",
"mocha": "^10.2.0", "mocha": "^10.2.0",
"nyc": "^15.1.0", "nyc": "^15.1.0",
"release-it": "^17.0.0", "release-it": "^17.0.3",
"tsx": "^4.6.2", "tsx": "^4.7.0",
"typedoc": "^0.25.4", "typedoc": "^0.25.7",
"typescript": "^5.3.2" "typescript": "^5.3.3"
} }
} }

View File

@@ -1,14 +1,17 @@
# @redis/bloom # @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: RedisBloom provides the following probabilistic data structures:
* Bloom Filter: for checking set membership with a high degree of certainty. * Bloom Filter: for checking set membership with a high degree of certainty.
* Cuckoo 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. * 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).

View File

@@ -17,6 +17,9 @@
"devDependencies": { "devDependencies": {
"@redis/test-utils": "*" "@redis/test-utils": "*"
}, },
"engines": {
"node": ">= 18"
},
"repository": { "repository": {
"type": "git", "type": "git",
"url": "git://github.com/redis/node-redis.git" "url": "git://github.com/redis/node-redis.git"

View File

@@ -17,8 +17,7 @@ export { RedisClusterType, RedisClusterOptions };
export const createCluster = RedisCluster.create; export const createCluster = RedisCluster.create;
import RedisSentinel from './lib/sentinel'; import RedisSentinel from './lib/sentinel';
import { RedisSentinelOptions, RedisSentinelType } from './lib/sentinel/types'; export { RedisSentinelOptions, RedisSentinelType } from './lib/sentinel/types';
export { RedisSentinelType, RedisSentinelOptions };
export const createSentinel = RedisSentinel.create; export const createSentinel = RedisSentinel.create;
// export { GeoReplyWith } from './lib/commands/generic-transformers'; // export { GeoReplyWith } from './lib/commands/generic-transformers';

View File

@@ -460,7 +460,9 @@ export default class RedisClient<
}) })
.on('reconnecting', () => this.emit('reconnecting')) .on('reconnecting', () => this.emit('reconnecting'))
.on('drain', () => this.#maybeScheduleWrite()) .on('drain', () => this.#maybeScheduleWrite())
.on('end', () => this.emit('end')); .on('end', () => {
console.log('socket on end, emitting end', this.emit('end'));
});
} }
#pingTimer?: NodeJS.Timeout; #pingTimer?: NodeJS.Timeout;

View File

@@ -88,7 +88,7 @@ async function steadyState(frame: SentinelFramework) {
} }
["redis-sentinel-test-password", undefined].forEach(function (password) { ["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 config: RedisSentinelConfig = { sentinelName: "test", numberOfNodes: 3, password: password };
const frame = new SentinelFramework(config); const frame = new SentinelFramework(config);
let tracer = new Array<string>(); let tracer = new Array<string>();

View File

@@ -1,4 +1,5 @@
import { RedisModules } from '@redis/client';
import { RedisModules } from '../RESP/types';
import sentinel from './commands'; import sentinel from './commands';
export default { export default {

View File

@@ -16,11 +16,11 @@
}, },
"devDependencies": { "devDependencies": {
"@redis/test-utils": "*", "@redis/test-utils": "*",
"@types/sinon": "^17.0.2", "@types/sinon": "^17.0.3",
"sinon": "^17.0.1" "sinon": "^17.0.1"
}, },
"engines": { "engines": {
"node": ">=14" "node": ">= 18"
}, },
"repository": { "repository": {
"type": "git", "type": "git",

View File

@@ -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;

View File

@@ -17,6 +17,9 @@
"devDependencies": { "devDependencies": {
"@redis/test-utils": "*" "@redis/test-utils": "*"
}, },
"engines": {
"node": ">= 18"
},
"repository": { "repository": {
"type": "git", "type": "git",
"url": "git://github.com/redis/node-redis.git" "url": "git://github.com/redis/node-redis.git"

View File

@@ -1,12 +1,14 @@
# @redis/json # @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 ## 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 ### 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`": Here, we'll store a JSON document in the root of the Redis key "`mydoc`":
```javascript ```javascript
import { createClient } from 'redis';
...
await client.json.set('noderedis:jsondata', '$', { await client.json.set('noderedis:jsondata', '$', {
name: 'Roberta McDonald', name: 'Roberta McDonald',
pets: [ pets: [{
{
name: 'Rex', name: 'Rex',
species: 'dog', species: 'dog',
age: 3, age: 3,
isMammal: true isMammal: true
}, }, {
{
name: 'Goldie', name: 'Goldie',
species: 'fish', species: 'fish',
age: 2, age: 2,
isMammal: false 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 ### 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 ```javascript
const results = await client.json.get('noderedis:jsondata', { const results = await client.json.get('noderedis:jsondata', {

View File

@@ -17,6 +17,9 @@
"devDependencies": { "devDependencies": {
"@redis/test-utils": "*" "@redis/test-utils": "*"
}, },
"engines": {
"node": ">= 18"
},
"repository": { "repository": {
"type": "git", "type": "git",
"url": "git://github.com/redis/node-redis.git" "url": "git://github.com/redis/node-redis.git"

View File

@@ -1,32 +1,5 @@
# Node-Redis # Node-Redis
[![Tests](https://img.shields.io/github/actions/workflow/status/redis/node-redis/tests.yml?branch=master)](https://github.com/redis/node-redis/actions/workflows/tests.yml)
[![Coverage](https://codecov.io/gh/redis/node-redis/branch/master/graph/badge.svg?token=xcfqHhJC37)](https://codecov.io/gh/redis/node-redis)
[![License](https://img.shields.io/github/license/redis/node-redis.svg)](https://github.com/redis/node-redis/blob/master/LICENSE)
[![Discord](https://img.shields.io/discord/697882427875393627.svg?style=social&logo=discord)](https://discord.gg/redis)
[![Twitch](https://img.shields.io/twitch/status/redisinc?style=social)](https://www.twitch.tv/redisinc)
[![YouTube](https://img.shields.io/youtube/channel/views/UCD78lHSwYqMlyetR0_P4Vig?style=social)](https://www.youtube.com/redisinc)
[![Twitter](https://img.shields.io/twitter/follow/redisinc?style=social)](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 ## Usage
### Basic Example ### Basic Example
@@ -43,7 +16,7 @@ const value = await client.get('key');
await client.close(); 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]`: 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). 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: To client exposes 2 `boolean`s that track the client state:
1. `isOpen` - the client is either connecting or connected. 1. `isOpen` - the client is either connecting or connected.
2. `isReady` - the client is connected and ready to send 2. `isReady` - the client is connected and ready to send
@@ -175,7 +150,7 @@ await Promise.all([
### Events ### 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 | | 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* | | `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) | | `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. ### Read more
### Links
- [Transactions (`MULTI`/`EXEC`)](../../docs/transactions.md). - [Transactions (`MULTI`/`EXEC`)](../../docs/transactions.md).
- [Pub/Sub](../../docs/pub-sub.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). - [Pool](../../docs/pool.md).
- [Clustering](../../docs/clustering.md). - [Clustering](../../docs/clustering.md).
- [Sentinel](../../docs/sentinel.md). - [Sentinel](../../docs/sentinel.md).
- [FAQ](../../docs/FAQ.md).
## Supported Redis versions ## Supported Redis versions

View File

@@ -17,6 +17,9 @@
"@redis/search": "2.0.0-next.2", "@redis/search": "2.0.0-next.2",
"@redis/time-series": "2.0.0-next.2" "@redis/time-series": "2.0.0-next.2"
}, },
"engines": {
"node": ">= 18"
},
"repository": { "repository": {
"type": "git", "type": "git",
"url": "git://github.com/redis/node-redis.git" "url": "git://github.com/redis/node-redis.git"

View File

@@ -1,18 +1,20 @@
# @redis/search # @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 ## 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 ### Indexing and Querying Data in Redis Hashes
#### Creating an Index #### 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 ```javascript
await client.ft.create('idx:animals', { await client.ft.create('idx:animals', {

View File

@@ -17,6 +17,9 @@
"devDependencies": { "devDependencies": {
"@redis/test-utils": "*" "@redis/test-utils": "*"
}, },
"engines": {
"node": ">= 18"
},
"repository": { "repository": {
"type": "git", "type": "git",
"url": "git://github.com/redis/node-redis.git" "url": "git://github.com/redis/node-redis.git"

View File

@@ -1,8 +1,10 @@
# @redis/time-series # @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 ## Usage
@@ -20,20 +22,18 @@ import { createClient } from 'redis';
import { TimeSeriesDuplicatePolicies, TimeSeriesEncoding, TimeSeriesAggregationType } from '@redis/time-series'; 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', { if (created === 'OK') {
RETENTION: 86400000, // 1 day in milliseconds console.log('Created timeseries.');
ENCODING: TimeSeriesEncoding.UNCOMPRESSED, // No compression - When not specified, the option is set to COMPRESSED } else {
DUPLICATE_POLICY: TimeSeriesDuplicatePolicies.BLOCK, // No duplicates - When not specified: set to the global DUPLICATE_POLICY configuration of the database (which by default, is BLOCK). 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 ### 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 ```javascript
let value = Math.floor(Math.random() * 1000) + 1; // Random data point value let value = Math.floor(Math.random() * 1000) + 1; // Random data point value
let currentTimestamp = 1640995200000; // Jan 1 2022 00:00:00 let currentTimestamp = 1640995200000; // Jan 1 2022 00:00:00
let num = 0; let num = 0;
while (num < 10000) { while (num < 10000) {
// Add a new value to the timeseries, providing our own timestamp: // Add a new value to the timeseries, providing our own timestamp:
// https://redis.io/commands/ts.add/ // https://redis.io/commands/ts.add/
await client.ts.add('temperature', currentTimestamp, value); await client.ts.add('temperature', currentTimestamp, value);
console.log(`Added timestamp ${currentTimestamp}, value ${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
}]);
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 ### 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: 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 ```javascript
// Query the timeseries with TS.RANGE: // Query the timeseries with TS.RANGE:
// https://redis.io/commands/ts.range/ // https://redis.io/commands/ts.range/
const fromTimestamp = 1640995200000; // Jan 1 2022 00:00:00 const fromTimestamp = 1640995200000; // Jan 1 2022 00:00:00
const toTimestamp = 1640995260000; // Jan 1 2022 00:01:00 const toTimestamp = 1640995260000; // Jan 1 2022 00:01:00
const rangeResponse = await client.ts.range('temperature', fromTimestamp, toTimestamp, { const rangeResponse = await client.ts.range('temperature', fromTimestamp, toTimestamp, {
// Group into 10 second averages. // Group into 10 second averages.
AGGREGATION: { AGGREGATION: {
type: TimeSeriesAggregationType.AVERAGE, type: TimeSeriesAggregationType.AVERAGE,
timeBucket: 10000 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 }
// ]
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 ### 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: Using the [`TS.ALTER`](https://redis.io/commands/ts.alter/) command, we can update time series retention like this:
```javascript ```javascript
// https://redis.io/commands/ts.alter/
// https://redis.io/commands/ts.alter/ const alterResponse = await client.ts.alter('temperature', {
const alterResponse = await client.ts.alter('temperature', { RETENTION: 0 // Keep the entries forever
RETENTION: 0 // Keep the entries forever });
});
``` ```
### Retrieving Information about the timeseries Stored in Redis ### 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: Using the [`TS.INFO`](https://redis.io/commands/ts.info/) command, we can view timeseries information like this:
```javascript ```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. // tsInfo looks like this:
// https://redis.io/commands/ts.info/ // {
const tsInfo = await client.ts.info('temperature'); // totalSamples: 1440,
// memoryUsage: 28904,
// tsInfo looks like this: // firstTimestamp: 1641508920000,
// { // lastTimestamp: 1641595320000,
// totalSamples: 1440, // retentionTime: 86400000,
// memoryUsage: 28904, // chunkCount: 7,
// firstTimestamp: 1641508920000, // chunkSize: 4096,
// lastTimestamp: 1641595320000, // chunkType: 'uncompressed',
// retentionTime: 86400000, // duplicatePolicy: 'block',
// chunkCount: 7, // labels: [],
// chunkSize: 4096, // sourceKey: null,
// chunkType: 'uncompressed', // rules: []
// duplicatePolicy: 'block', // }
// labels: [],
// sourceKey: null,
// rules: []
// }
``` ```

View File

@@ -17,6 +17,9 @@
"devDependencies": { "devDependencies": {
"@redis/test-utils": "*" "@redis/test-utils": "*"
}, },
"engines": {
"node": ">= 18"
},
"repository": { "repository": {
"type": "git", "type": "git",
"url": "git://github.com/redis/node-redis.git" "url": "git://github.com/redis/node-redis.git"

View File

@@ -1,8 +1,8 @@
{ {
"compilerOptions": { "compilerOptions": {
"lib": ["ES2023"], "lib": ["ES2023"],
"module": "CommonJS", "module": "NodeNext",
"moduleResolution": "Node", "moduleResolution": "NodeNext",
"target": "ES2022", "target": "ES2022",
"strict": true, "strict": true,
@@ -12,7 +12,9 @@
"skipLibCheck": true, "skipLibCheck": true,
"composite": true, "composite": true,
"sourceMap": true,
"declaration": true, "declaration": true,
"declarationMap": true,
"allowJs": true "allowJs": true
} }
} }