{"id":19370045,"url":"https://github.com/bustle/radredis","last_synced_at":"2025-04-23T15:31:49.065Z","repository":{"id":36203184,"uuid":"40507426","full_name":"bustle/radredis","owner":"bustle","description":"Basic redis backed object modeling for Node.","archived":false,"fork":false,"pushed_at":"2018-03-08T05:06:06.000Z","size":103,"stargazers_count":19,"open_issues_count":13,"forks_count":3,"subscribers_count":11,"default_branch":"master","last_synced_at":"2025-04-02T17:11:12.315Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bustle.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-08-10T21:37:50.000Z","updated_at":"2022-01-31T00:07:57.000Z","dependencies_parsed_at":"2022-09-05T18:30:43.690Z","dependency_job_id":null,"html_url":"https://github.com/bustle/radredis","commit_stats":null,"previous_names":["bustlelabs/radredis"],"tags_count":26,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bustle%2Fradredis","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bustle%2Fradredis/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bustle%2Fradredis/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bustle%2Fradredis/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bustle","download_url":"https://codeload.github.com/bustle/radredis/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250460473,"owners_count":21434253,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-10T08:14:04.121Z","updated_at":"2025-04-23T15:31:48.764Z","avatar_url":"https://github.com/bustle.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Radredis\n\n[![Build Status](https://travis-ci.org/bustlelabs/radredis.svg?branch=master)](https://travis-ci.org/bustlelabs/radredis)\n\nRadredis is a node data adapter for redis.\nIt is not a full ORM but a simple opinionated interface for storing application data in redis.\n\n## Goals\n\n- Use json-schema for data validation\n- No classes. No `new` keyword. Factory functions.\n- Before/After transforms\n- Promise based\n- Pipelining. All redis commands are executed via transaction if possible.\n- iodredis under the hood.\n\n## Setup\n\n``` js\nconst Radredis = require('radredis')\nconst redisOpts = { db: 15, keyPrefix: 'your-app:' }\nconst transforms = { beforeSave: (model) =\u003e model.title = model.title.toLowerCase() }\nconst schema = {\n  title: 'Post',\n  type: \"object\"\n  properties : {\n    title: {\n      type: 'string'\n    },\n    author_id: {\n      type: 'number'\n    }\n  }\n}\n\nconst Post = Radredis(schema, transforms, redisOpts)\n```\n\n## Redis configuration\n\nThe final three arguments to `Radredis` are passed through to `ioredis`. See their documentation for more info: https://github.com/luin/ioredis/blob/master/API.md#new_Redis_new\n\nExamples:\n\n``` js\n// Radredis(schema, transforms, [port], [host], [options])\nconst Post = Radredis(schema, transforms, {db: 15})\nconst Post = Radredis(schema, transforms, 6379, 'localhost', {db: 15})\nconst Post = Radredis(schema, transforms, 'redis://user:password@localhost:6379/15')\n```\n\n## All\n\n``` js\nPost.all()\n// =\u003e [ post, post, post, ...]\n\n// All with limit and offset\nPost.all({ limit: 2, offset: 10 })\n// =\u003e [ post, post ]\n\n// All by index\n// Note order is currently always descending\nPost.all({ index: 'author_id' } )\n\n// Return only certain properties\nPost.all({ properties: ['author_id'] } )\n```\n\n## Range\n\nAllows for retrieving records by range of values for an attribute.\n- Results ordered in descending value\n- Results are inclusive of `min` and `max`\n- `min`, `max`, and `index` are required\n\n``` js\nPost.range({ index: 'author_id', min: 1, max: 2})\n// =\u003e [ post, post, post, ...]\n\n// Also accepts limit and offset\nPost.range({ index: 'author_id', min: 1, max: 2, limit: 2, offset: 10 })\n// =\u003e [ post, post ]\n\n// Return only certain properties\nPost.range({ index: 'author_id', min: 1, max: 2, properties: ['author_id'] })\n```\n\n## Scan\n\n``` js\nconst stream = Post.scan()\nstream.on('data', (post) =\u003e { console.log(post) })\nstream.on('end', () =\u003e { console.log( 'Read all posts!') }\n\n// =\u003e { id: 1, title: 'A title', author_id: 1 },\n// =\u003e { id: 2, title: 'Another title', author_id: 2 }\n// ...\n// =\u003e Read all posts!\n\n// You can scan only a specific index by passing the index name to scan\nconst stream = Post.scan('published_at')\nstream.on('data', (post) =\u003e { console.log(post) })\nstream.on('end', () =\u003e { console.log( 'Read only published posts!') }\n\n// =\u003e { id: 1, title: 'A title', author_id: 1 },\n// =\u003e { id: 2, title: 'Another title', author_id: 2 }\n// ...\n// =\u003e Read only published posts!\n```\n\n``` js\n// Return only specific fields\nconst stream = Post.scan('published_at', ['author_id'])\nstream.on('data', (post) =\u003e { console.log(post) })\n\n// =\u003e { id: 1, author_id: 1 },\n// =\u003e { id: 2, author_id: 2 }\n// ...\n```\n\n## Count\n\n``` js\nPost.count()\n// =\u003e 42\n\n// Count by index\nPost.count({ index: 'published' } )\n// =\u003e 35\n```\n\n## Find\n\n\n``` js\n// Find one\nPost.find(1)\n// =\u003e { id: 1, title: 'A title', author_id: 1 }\n\n// Find multiple\nPost.find([1, 2, 3])\n// =\u003e [ { id: 1, title: 'A title', author_id: 1 }, { id: 2, title: 'Another title', author_id: 2 } ]\n```\n\n## Create\n\n``` js\nPost.create({title: 'Redis rocks'})\n// =\u003e { id: 1, title: 'Redis rocks' }\n\n```\n\n## Update\n\nDoes a partial update of the model. Basically Object.assign(old, new)\n\n``` js\nPost.create(1, { author: 5 })\nPost.update(1, { title: 'A new title'})\n// =\u003e {id: 1, title: 'A new title', author: 5 }\n```\n\n## Replace\n\nCompletely replaces the model in the database with the provided attributes\n\n``` js\nPost.create(1, { author: 5 })\nPost.replace(1, { title: 'A new title'})\n// =\u003e {id: 1, title: 'A new title'}\n```\n\n## Delete\n\n``` js\nPost.delete(1)\n// =\u003e {id: 1, title: 'A new title'}\n```\n\n## Versions\n\nSee versioning below. Will return all versions of an object including the most recent one.\n\n``` js\nPost.create({ title: 'foo'})\nPost.update(1, { title: 'bar'})\n// =\u003e [ {id: 1, _v: 1, title: 'foo'}, {id: 1, _v: 2, title: 'bar'} ]\n```\n\n## Validation\n\n*NOT IMPLEMENTED*\n\nValidation is handled by json-schema (http://json-schema.org/examples.html)\nFunctions return promise rejections if bad data\n\n## Indexing\n\nSpecify indexed attributes inside json schema:\n``` js\nconst schema = {\n  title: 'Post',\n  type: \"object\"\n  properties : {\n    author_id: {\n      type: 'number',\n      index: true\n    }\n  }\n}\n```\n\n## Versioning\n\nSpecify attributes that should create a new version when changed inside json schema. The version number is in the `_v` key of the record\n``` js\nconst schema = {\n  title: 'Post',\n  type: \"object\"\n  properties : {\n    author_id: {\n      type: 'number',\n      index: true\n    },\n    title: {\n      type: 'string'\n      version: true\n    }\n  }\n}\n```\n\n\n## Transforms\n\n\n``` js\n\n// Note oldAttributes will be undefined on create\n{\n  beforeSave: (oldModel, newModel) =\u003e { /*do stuff to attributes*/},\n  afterSave: (savedModel) =\u003e { /*do stuff with attributes*/}\n}\n```\n\n## Errors\n\nradredis will throw a `RecordNotFound` error on any operation where the record does not exist.\n\n``` js\n\nimport radredis from 'radredis'\n\n// Can also do:\n//import { default as radredis, RecordNotFound } from 'radredis'\n\nconst Post = radredis(schema, transforms, redisOpts)\n\nPost.find(999).catch(radredis.RecordNotFound, (err) =\u003e console.log(err) )\n\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbustle%2Fradredis","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbustle%2Fradredis","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbustle%2Fradredis/lists"}