Alpha018/nestjs-redisom
Seamlessly integrate Redis OM into NestJS. Define schemas with decorators, inject repositories, and unlock the power of Redis Stack JSON & Search.
This library seamlessly integrates RedisOM into NestJS, offering:
@Schema and @Prop.@InjectRepository.forRoot or forRootAsync.npm install @alpha018/nestjs-redisom redis-om redis
Use the @Schema() decorator to define your entity and @Prop() for properties. Extends BaseEntity to easily access the auto-generated ID.
import { Schema } from 'nestjs-redisom';
import { Prop } from 'nestjs-redisom';
import { BaseEntity } from 'nestjs-redisom';
@Schema()
export class CatEntity extends BaseEntity {
@Prop()
name: string;
@Prop()
age: number;
}
Note: For all available property decorators, indexing options, and schema definitions, see the Wiki: Defining Structures.
No download data available
No tracked packages depend on this.
Register RedisOmModule in your root AppModule and register your entities with forFeature.
import { Module } from '@nestjs/common';
import { RedisOmModule } from 'nestjs-redisom';
import { CatEntity } from './cat.entity';
@Module({
imports: [
RedisOmModule.forRoot({
url: 'redis://localhost:6379'
}),
RedisOmModule.forFeature([CatEntity]),
],
})
export class AppModule {}
Note: For advanced connection setups, environmental validation, and asynchronous options, see the Wiki: Configuration.
Inject the repository to save and search for entities.
import { Injectable } from '@nestjs/common';
import { InjectRepository } from 'nestjs-redisom';
import { Repository } from 'redis-om';
import { CatEntity } from './cat.entity';
@Injectable()
export class CatsService {
constructor(
@InjectRepository(CatEntity) private readonly catRepo: Repository<CatEntity>,
) {}
async create(name: string, age: number) {
const entity = new CatEntity();
entity.name = name;
entity.age = age;
return await this.catRepo.save(entity);
}
async findAll() {
return await this.catRepo.search().return.all();
}
}
Note: To learn about all search capabilities and query building, see the Wiki: Searching.
You can define nested objects using classes and the @Prop({ type: () => Class }) syntax. This allows Redis OM to automatically generate the correct schema fields for your nested data.
How it works:
The library flattens nested properties into the Redis schema using the format parentProperty_childProperty (underscore separator). This allows you to index and search deeply nested fields without complex JSON path syntax.
Define the Embedded Class:
export class Address {
@Prop({ indexed: true })
street: string;
@Prop({ indexed: true })
city: string; // Will become 'address_city' in the schema
}
Use in Parent Entity:
@Schema({ dataStructure: 'JSON' })
export class Person extends BaseEntity {
@Prop()
name: string;
@Prop({ type: () => Address })
address: Address;
}
Search using flattened/nested fields:
Since the schema uses flattened keys, you query them using the underscore syntax:
// Search for persons where address.city is 'New York'
const results = await this.personRepo.search()
.where('address_city' as any) // Use the flattened key
.eq('New York')
.return.all();
Note: Discover more about embedded objects and array structures in the Wiki: Defining Structures.
You can explicitly set the ID when saving an entity if you don't want to use the auto-generated ULID. This is useful for using existing IDs (like UUIDs, emails, or external system IDs).
// Using a UUID
import { v4 as uuidv4 } from 'uuid';
const id = uuidv4();
await this.catRepo.save(id, entity);
// Using a custom string
await this.catRepo.save('unique-custom-id', entity);
Note: Read more about identifier strategies in the Wiki: Defining Structures.
You can set an expiration time (in seconds) for an entity. The key will automatically be deleted from Redis after the specified time.
const id = 'temp-session-123';
await this.catRepo.save(id, sessionEntity);
// Expire after 60 seconds
await this.catRepo.expire(id, 60);
Note: See entity expiration patterns in the Wiki: Defining Structures.
For secure connections (e.g., AWS ElastiCache, Redis Cloud), use the rediss:// protocol and provide TLS options in the socket configuration.
Static Configuration:
import * as fs from 'fs';
RedisOmModule.forRoot({
url: 'rediss://your-redis-instance:6380',
socket: {
tls: true,
rejectUnauthorized: false, // Set to true if using a public CA
// ca: fs.readFileSync('path/to/ca.pem'), // Optional: Load custom CA
},
})
Async Configuration (e.g., using ConfigService):
RedisOmModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: (config: ConfigService) => ({
url: config.get('REDIS_URL'), // e.g., 'rediss://...'
socket: {
tls: true,
rejectUnauthorized: config.get('REDIS_TLS_REJECT_UNAUTHORIZED') === 'true',
},
}),
})
Note: Find more cloud connection examples in the Wiki: Configuration.
nestjs-redisom natively supports connecting to a Redis Cluster using the underlying createCluster functionality of Node-Redis.
Instead of providing a single url, you provide an array of rootNodes:
RedisOmModule.forRoot({
rootNodes: [
{ url: 'redis://redis-cluster-node-1:7000' },
{ url: 'redis://redis-cluster-node-2:7000' }
],
defaults: {
password: 'your-cluster-password'
}
})
Note: For full details on how the Node-Redis client uses these initial nodes for cluster auto-discovery (
CLUSTER SLOTS), please refer to the Configuration Wiki.
useFactory, useClass, and useExisting for configuration.class-validator (standard NestJS practice).This library leverages RediSearch (module of Redis Stack), meaning searches are efficient and non-blocking.
When you use @Prop({ indexed: true }), Redis OM creates an Inverted Index.
repo.search()... queries this index directly. It does NOT perform a linear scan (SCAN command) over the keyspace.| Data Type | Operation | Complexity | Notes |
|---|---|---|---|
| ID | Retrieve (fetch) | O(1) | Direct key access (fastest). |
| Tag / String | Exact Match (eq) | O(K) | K = number of results returned. |
| Numeric / Date | Range (gt, lt, between) | O(log N + K) | Uses sorted sets/trees. efficient for ranges. |
| Text | Full-Text (matches) | O(M + K) | M = number of terms/words being searched. |
| Geo | Radius / Polygon | O(K + log N) | Geospacial indexing. |
save) are lightweight.Check out a few resources that may come in handy when working with NestJS:
Nest is an MIT-licensed open source project. It can grow thanks to the sponsors and support by the amazing backers. If you'd like to join them, please read more here.
NestJS RedisOM is MIT licensed.