redismn
v1.0.27
Published
RedisExp is a Node.js library that simplifies interactions with Redis-Stack. It provides an intuitive API for storing documents, querying, atomic transactions, and advanced aggregations.currently fully supported fo json (every feature).(hset ,set ,zset,ti
Readme
RedisExp - Simplified Redis client library.
RedisExp is a Node.js library that simplifies interactions with Redis-Stack. It provides an intuitive API for storing documents, querying, atomic transactions, and advanced aggregations.currently fully supported fo json (every feature).(hset ,set ,zset,timeseries and bloom are currently developed by us)
Help this project to improve
We welcome contributions of all kinds — bug fixes, new features, documentation improvements, or even just ideas! If you’re interested in helping improve redismn, check out our CONTRIBUTING.md to get started.
update -
- connection bug resolve -before this update there is no option of username and password to connect.
- important note - whenever you use tag type for searching you must enclose value in {} for all methods ex -
redis.jsonquery("gender","{female}","user")in this update a new method is addded jsongetmultkey()
- usage -
await redis.jsongetmultkey("user","first_name","last_name").keys("us1","us2","usn");output=[{first_name:"john","last_name:"doe"},{first_name:"mari","last_name:"doe",age:70,married:true},{first_name:"mariana","last_name:"jane",age:55,married:true}]
fields not specified
await redis.jsongetmultkey("user").keys("us1","us2","usn");
output=[{first_name:"john","last_name:"doe",age:78,married:true},{first_name:"mari","last_name:"doe",age:70,married:true},null] null if not avaiible
if only one field specified
await redis.jsongetmultkey("user","first_name").keys("us1","us2","usn");
output=["john","mari",null]
Features
- CRUD Operations: Store, retrieve, and update JSON documents.
- Index Management: Define search schemas for efficient querying.
- Flexible Queries: Perform text, range, and key-value searches.
- Atomic Transactions: Chain multiple operations in a single transaction.
- Aggregation Pipelines: Group, filter, sort, and reduce data with method chaining.
- update after aggregate: after filter,sort and limit you can update those fields(atomic operation ,no multiple queries(single query))
Got it! Here's the updated README snippet with the correct function name:
update.
🔄 new feature – Update Values for WhereAggregator (Atomically)
This function is used by WhereAggregator to update values it finds, and it's optimized for atomic performance – no need to worry about slowdowns!
Usage
update(arrofrequiredfieldforop, pathinput, method, eqn);Parameters
arrofrequiredfieldforop(string[]):
An array of required field names from your schema used in the equation.pathinput(string):
A simple JSON path to the field you want to update.
Example: For an object like{ name: 'john doe', data: { friends: [] } }, use:"data.friends"method(string):
The update method.- Currently only
"set"is supported. "push"will be added soon.
- Currently only
eqn(string):
A string equation using the following operators:- Arithmetic:
+,-,*,/ - Concatenation:
&
Important notes: - No brackets supported — expressions are evaluated left to right.
- Only use keys from the schema and direct values.
- Example:
"2+age*6&first_name" // Interpreted as: ((2 + age) * 6) & first_name
- Arithmetic:
A version that supports full BODMAS (order of operations) will be released later with a trade-off in performance.
Let me know if you want to include example input/output or a quick visual of how eqn is parsed!
Installation
Ensure Redis is running with RedisJSON and RediSearch modules.
npm install redismnUsage
Initialize Client
import RedisExp from 'redismn';
const redis = new RedisExp("localhost", 6379);
await redis.start(); // Connects to RedisDefine Schema
Create a search index to enable queries on specific fields.
await redis.jsonSchemaIdx("User", [
{ key_name: "id", tag_type: "NUMERIC", sortable: true },
{ key_name: "name", tag_type: "TEXT", sortable: true },
{ key_name: "age", tag_type: "NUMERIC" }
]);Store Data
await redis.jsonset("user1", { name: "Alice", age: 30 }, "User", 3600);
// Expires in 1 hourRetrieve Data
Get entire object:
const user = await redis.jsongetAll("user1", "User");
console.log(user); // { name: "Alice", age: 30 }Get nested property:
const age = await redis.jsonget("user1", "age", "User");
console.log(age); // 30Query Data
Key-value search:
const results = await redis.jsonquery("name", "Alice", "User");
console.log(results); // Array of matching documentssee availible queries using 'jsonqueryTextavailible' function
Full-text search:
const results = await redis.jsonqueryText("@age:[25 35]", "User");
// Returns users aged 25-35
Atomic Transactions
where has two parameters modelname and ttl.
you can add as many as you want jsonset and jsonget.
Chain jsonset and jsonget in a single Redis call:
const transaction = await redis.where("User")
.jsonset("user2", { name: "Bob", age: 25 })
.jsonget("user1", "")
.exec();
console.log(transaction); // [ { name: "Alice", age: 30 } ]Aggregation Queries
Filter and group:
const result = await redis.whereagregater("User")
.jsonnumrange("age", 20, 40)
.jsongroup("age")
.jsonaccumulator("age", "SUM")
.exec();
console.log(result);
// [ { age_SUM: "55" } ] (Sum of ages in 20-40 group)Sort and limit:
const result = await redis.whereagregater("User")
.jsonsort("age", "DESC")
.jsonskiplimit(0, 5)
.exec("name", "age");
console.log(result);
// Top 5 oldest users with name and age fieldsAPI Reference
Core Methods
jsonset(key, jsonobj, model_name, ttl)
- key: Unique identifier.
- jsonobj: JSON object to store.
- model_name: Namespace (like a collection).
- ttl: Optional expiration in seconds.
jsongetAll(key, model_name)
- Returns the entire JSON object stored at
key.
jsonget(key, pathinput, model_name)
- pathinput: Dot-separated path to nested property (e.g.,
"address.city").
jsonSchemaIdx(model_name, key_tag_arr)
- key_tag_arr: Array of objects defining index schema:
{ key_name: "field", tag_type: "TEXT|NUMERIC|TAG", sortable: true }
Query Methods
jsonquery(key, val, model_name)
- Key-value search (supports numeric and text values).
jsonqueryText(query, model_name)
- query: RediSearch query string (e.g.,
"@age:[20 30]").
Aggregation Builder (via whereagregater)
Methods are chainable before calling exec():
Filtering:
jsonnumrange(key, min, max): Numeric range filter.jsonequals(key, value): Exact match.jsongte(key, value): Greater than or equal.
Grouping:
jsongroup(key): Group by a field.jsonaccumulator(key, reducer): Apply reducers (SUM,MAX,TOLIST).
Sorting/Pagination:
jsonsort(key, order): Sort results (ASC/DESC).jsonskiplimit(offset, count): Paginate results.
Complex Aggregation
const salesReport = await redis.whereagregater("Sales")
.jsonnumrange("amount", 100, 1000)
.jsongroup("product")
.jsonaccumulator("amount", "SUM")
.jsonsort("SUM_amount", "DESC")
.exec("product", "SUM_amount");
console.log(salesReport);
// [ { product: "Widget", SUM_amount: "4500" }, ... ]jsdoc
RedisExp API Documentation
A Node.js wrapper for RedisJSON and RediSearch operations. Provides methods for CRUD, indexing, querying, transactions, and aggregations.
Core Methods
jsonset(key, jsonobj, model_name, ttl)
- Description: Stores a JSON object under a key with optional TTL.
- Parameters:
key(String): Unique identifier (e.g.,"user1").jsonobj(Object): JSON data to store (e.g.,{ name: "Alice" }).model_name(String): Namespace for data organization (e.g.,"User").ttl(Number, Optional): Expiration time in seconds.
- Throws: Error if
key,jsonobj, ormodel_nameare missing.
jsongetAll(key, model_name)
- Description: Retrieves the full JSON object by key.
- Parameters:
key(String): Object identifier.model_name(String): Namespace.
- Returns: (Object | undefined) Parsed JSON or
undefinedif not found.
jsongetmultkey()
- usage -
await redis.jsongetmultkey("user","first_name","last_name").keys("us1","us2","usn");output=[{first_name:"john","last_name:"doe"},{first_name:"mari","last_name:"doe",age:70,married:true},{first_name:"mariana","last_name:"jane",age:55,married:true}]
fields not specified
await redis.jsongetmultkey("user").keys("us1","us2","usn");
output=[{first_name:"john","last_name:"doe",age:78,married:true},{first_name:"mari","last_name:"doe",age:70,married:true},null] null if not avaiible
if only one field specified
await redis.jsongetmultkey("user","first_name").keys("us1","us2","usn");
output=["john","mari",null]
jsonget(key, pathinput, model_name)
- Description: Fetches a nested property using a dot path.
- Parameters:
key(String): Object identifier.pathinput(String): Path to nested property (e.g.,"data.friends).model_name(String): Namespace.
- Returns: (any | undefined) Property value or
undefined.
jsonSchemaIdx(model_name, key_tag_arr)
- Description: Creates a search index schema.
- Parameters:
model_name(String): Namespace.key_tag_arr(Array): Schema definitions:key_name(String): JSON field name.tag_type(String):"TEXT","NUMERIC","TAG", or"ARRAY".sortable(Boolean, Optional): Enable sorting.arr_type(String, Required iftag_type="ARRAY"): Type of array elements.
Query Methods
jsonquery(key, val, model_name, preprocessor_optional)
- Description: Key-value search (exact match).
- Parameters:
key(String): Field name (e.g.,"age").val(String | Number): Value to match.model_name(String): Namespace.preprocessor_optional(Function, Optional): Custom result parser.
- Returns: (Array<[key, Object]>) Matched entries.
jsonqueryText(val, model_name, preprocessor_optional)
- Description: Full-text search using RediSearch syntax.
- Parameters:
val(String): Query string (e.g.,"@age:[20 30]").model_name(String): Namespace.preprocessor_optional(Function, Optional): Custom parser.
- Returns: (Array<[key, Object]>) Matched entries.
Atomic Transactions
where(model_name, ttl)
- Description: Chains multiple operations in a single transaction.
- Parameters:
model_name(String): Namespace.ttl(Number, Optional): Default TTL for writes.
- Returns:
queryconstructorinstance with methods:.jsonset(key, jsonobj): Queue a write..jsonget(key, pathinput): Queue a read..exec(): Execute all queued operations atomically.
Example:
await redis.where("User", 3600)
.jsonset("user2", { name: "Bob" })
.jsonget("user1", "")
.exec();Aggregation Queries
whereagregater(model_name)
- Description: Builds aggregation pipelines (filter, group, sort).
- Parameters:
model_name(String): Namespace.
- Returns:
advancequeriesinstance with methods:
| Method | Parameters | Description |
|--------|------------|-------------|
| jsonnumrange(key, min, max) | key (String), min/max (Number) | Numeric range filter. |
| jsonequals(key, value) | key (String), value (any) | Exact value match. |
| jsonskiplimit(offset, number) | offset (Number), number (Number) | Pagination. |
| jsongroup(key) | key (String) | Group by field. |
| jsonaccumulator(key, reducer) | key (String), reducer ("SUM", "MAX", etc.) | Aggregate grouped data. |
| exec(...keys) | ...keys (String, Optional) | Execute pipeline and return selected fields. |
Example:
const report = await redis.whereagregater("Sales")
.jsonnumrange("amount", 100, 500)
.jsongroup("product")
.jsonaccumulator("amount", "SUM")
.exec("product", "SUM_amount");Helper Methods
jsonqueryTextavailible()
- Returns: (Object) Query syntax cheat sheet for
jsonqueryText.
{
"simpletext": "Search for text in any field",
"@key:value": "Exact field match",
"@key:[min max]": "Numeric range",
// ... (see code for full list)
}Example Usage
Bulk Insert with TTL
await redis.where("User", 3600) // TTL 1 hour
.jsonset("user3", { name: "Carol", age: 28 })
.jsonset("user4", { name: "Dave", age: 32 }).jsonget("user4","")
.exec();
// Define schema
await redis.jsonSchemaIdx("User", [
{ key_name: "id", tag_type: "NUMERIC", sortable: true },
{ key_name: "name", tag_type: "TEXT" }
]);
// Insert data
await redis.jsonset("alice", { id: 1, name: "Alice" }, "User", 3600);
// Query
const user = await redis.jsongetAll("alice", "User");
console.log(user); // { id: 1, name: "Alice" }
// Full-text search
const results = await redis.jsonqueryText("@name:Alice", "User");