{"id":22010069,"url":"https://github.com/pilotpirxie/recommendation-redis","last_synced_at":"2025-08-24T21:16:04.022Z","repository":{"id":51131877,"uuid":"520255535","full_name":"pilotpirxie/recommendation-redis","owner":"pilotpirxie","description":"🦝 Simple and open source recommendation system powered by Redis","archived":false,"fork":false,"pushed_at":"2022-08-31T23:05:51.000Z","size":8702,"stargazers_count":9,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-05-06T19:06:52.292Z","etag":null,"topics":["redis","redis-database","redis-server","redishackathon","redishackathon2022"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pilotpirxie.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-08-01T20:37:57.000Z","updated_at":"2025-04-23T16:23:27.000Z","dependencies_parsed_at":"2022-08-12T22:40:35.928Z","dependency_job_id":null,"html_url":"https://github.com/pilotpirxie/recommendation-redis","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/pilotpirxie/recommendation-redis","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pilotpirxie%2Frecommendation-redis","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pilotpirxie%2Frecommendation-redis/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pilotpirxie%2Frecommendation-redis/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pilotpirxie%2Frecommendation-redis/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pilotpirxie","download_url":"https://codeload.github.com/pilotpirxie/recommendation-redis/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pilotpirxie%2Frecommendation-redis/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":271953126,"owners_count":24849290,"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","status":"online","status_checked_at":"2025-08-24T02:00:11.135Z","response_time":111,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["redis","redis-database","redis-server","redishackathon","redishackathon2022"],"created_at":"2024-11-30T02:11:53.582Z","updated_at":"2025-08-24T21:16:03.903Z","avatar_url":"https://github.com/pilotpirxie.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp style=\"text-align: center;\" align=\"center\"\u003e\n \u003cimg src=\"img/logo.png\" style=\"max-width: 100%;\" width=\"250\" alt=\"Recommendation\"/\u003e\n\u003c/p\u003e\n\n# recommendation\nOpen source recommendation system based on time-series data and statistical analysis. Written in ``TypeScript`` and ``Node.js`` using ``Redis`` for storage. The recommendation system uses the ``Jaccard index`` to calculate the intersection between two sets. One set is represented by the maximum possible sum of tag score and the other set is the score sum of user events per tag. The higher the Jaccard index, the higher the recommendation. It uses numbers to represent sets to increase performance.\n\n## Features\n* Use tag score and Jaccard index\n* Content-based filtering\n* Event-driven powered engine\n* Naive exploration of new tags\n* Suitable for product and content recommendation\n* Fine-tuning of tag weights\n* Minimalist and lightweight\n* Written in TypeScript and Node.js\n\n\u003cp style=\"text-align: center;\" align=\"center\"\u003e\n \u003cimg src=\"img/architecture.png\" style=\"max-width: 100%;\" width=\"500\" alt=\"Recommendation Architecture\"/\u003e\n\u003c/p\u003e\n\n## Overview video\n\u003cp style=\"text-align: center;\" align=\"center\"\u003e\n  \u003ca target=\"_blank\" href=\"https://www.youtube.com/watch?v=_m1BandnVsQ\" style=\"text-align: center;\"\u003e\n  \u003cimg src=\"img/thumbnail.png\" style=\"max-width: 100%;\" width=\"500\" alt=\"Video\"/\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n## How it works\n\n### How the data is stored:\n* Actors are stored in Redis as simple ``String`` keys with create date ``timestamps`` as value.\n* Items are ``Set`` type with ``tags`` as members. The item may have multiple tags.\n* Events are ``String`` type with ``actorId:id:tag:timestamp:ttl`` and an expire attribute set to ensure freshness of recommendations.\n\n### How the data is accessed:\n* Get the actor with events\n  * Check if the actor exists with ``EXISTS actor:${id}``\n  * Get all user events with ``SCAN ${loop cursor} MATCH actor:${id}``\n* Delete a single actor\n  * Scan for each related to actor key ``SCAN ${loop cursor} MATCH actor:${id}*``\n  * For each key delete with ``DEL ${key}``\n* Add a single actor\n  * Scan for each related to actor key ``SCAN ${loop cursor} MATCH actor:${id}*``\n  * For each key delete with ``DEL ${key}``\n  * Add new actor with ``SET actor:${id} ${Date.now().toString()}``\n* Add a single event\n  * Check if actor exists if flag is set using ``EXISTS actor:${id}``\n  * Add event with ``SET actor:${id}:${tag}:${date}:${ttl} ${score}``\n  * If ``TTL`` has been provided, set expiration for event with ``EXPIRE actor:${id}:${tag}:${date}:${ttl} ${ttl}``\n* Get all items with tags\n  * Get all items with ``SCAN ${loop cursor} MATCH item:*``\n  * For each item get all tags with ``SMEMBERS ${itemKey}``\n* Get a single item with tags\n  * Get all tags of item with ``SMEMBERS item:${id}``\n* Delete single item\n  * Call with ``DEL item:${id}``\n* Add a single item\n  * Check if item already exists ``EXISTS item:${id}``\n  * If so, then remove ``DEL item:${id}``\n  * And add item with tags ``SADD item:${id} ${tags}``\n\n## How to run it locally?\n```sh\n# clone repository with the source code\ngit clone\n\n# install dependencies\nyarn\n\n# build the application from ts to js\nyarn build\n\n# start the application\nyarn start\n\n# alternatively use ts-node in the developer mode\nyarn dev\n```\n\n## Deployment\nTo make deploys work, you need to create free account on [Redis Cloud](https://redis.info/try-free-dev-to)\n\n### Google Cloud Run\n\u003ca href=\"https://deploy.cloud.run\"\u003e\n  \u003cimg src=\"https://deploy.cloud.run/button.svg\" alt=\"Deploy\" width=\"250\"\u003e\n\u003c/a\u003e\n\n## Tests\nTo run tests use the following command:\n```sh\nyarn test\n```\nYou should see the following output:\n```ts\n PASS  src/__tests__/recommendations.spec.ts\n  Recommendations\n    √ should item 1 has score 1 and be the first (7 ms)\n    √ should item 2 has score 1 and be the first (1 ms)\n    √ should return two recommendation with the same score of 1 (1 ms)\n    √ should return two recommendation with the same score of 0.5\n    √ should return three recommendation with 1, 1 and 0.5 score\n\n PASS  src/__tests__/envs.spec.ts\n  Envs\n    √ should return one recommendation (2 ms)\n    √ should return two recommendations\n    √ should return recommendation with 0.125 score (1 ms)\n    √ should return recommendation with 0.0625 score\n    √ should clamp results to 0\n```\n\n### Environment variables\n```sh\n# redis host\nREDIS_HOST=\"localhost\"\n\n# redis port\nREDIS_PORT=\"6379\"\n\n# redis password\nREDIS_PASSWORD=\"mysecretpassword\"\n\n# write additional logs to stdout\nVERBOSE=\"true\"\n\n# do not check if an actor exists when adding an event\nDO_NOT_CHECK_ACTOR_EXISTENCE=\"true\"\n\n# maximum size of a candidate pool of items to calculate recommendation positions\nITEMS_LIMIT=\"100000\"\n\n# maximum number of events to use for recommendation calculation\nEVENTS_LIMIT=\"100000\"\n\n# maximum number of recommendations to return\nRECOMMENDATIONS_LIMIT=100\n\n# wait to finish event insertion before http response\nWAIT_FOR_EVENT_INSERTION=\"false\"\n\n# chance of recommending irrelevant item, used for exploration of new tags\n# to minimize the recommendation bubble effect\nEXPLORATION_NOISE=\"0.1\"\n\n# max sum of events score set per tag\n# e.g. 1 (view event) + 2 (like event) + 5 (lead event) = 8 \nJACCARD_MAX_TAG_SCORE=\"8\"\n\n# clamp the recommendation results between 0 and 1\nJACCARD_CLAMP_RESULT_RECOMMENDATIONS=\"true\"\n```\n\n### API\nSet (add or replace) actor\n```ts\nPOST /api/actors\n{\n    \"externalId\": \"string\"\n}\n```\n\nGet specific actor by actorId\n```ts\nGET /api/actors/:actorId\n```\n\nGet recommendation for actor\n```ts\nGET /api/actors/:actorId/recommendation\n```\n\nDelete specific actor\n```ts\nDELETE /api/actors/:actorId\n```\n\nAdd new event to an actor\n```ts\nPOST /api/actors/:actorId/events\n{\n    \"tag\": \"tag1\",\n    \"score\": 3,\n    \"ttl\": 60\n}\n```\n\nSet (add or replace) item\n```ts\nPOST /api/items\n{\n    \"externalId\": \"string\",\n    \"tags\": [\"tag1\", \"tag2\", \"...\"]\n}\n```\n\nGet specific item by itemId\n```ts\nGET /api/items/:itemId\n```\n\nDelete specific item\n```ts\nDELETE /api/items/:itemId\n```\n\n## More Information about Redis Stack\n\nHere some resources to help you quickly get started using Redis Stack. If you still have questions, feel free to ask them in the [Redis Discord](https://discord.gg/redis) or on [Twitter](https://twitter.com/redisinc).\n\n### Getting Started\n\n1. Sign up for a [free Redis Cloud account using this link](https://redis.info/try-free-dev-to) and use the [Redis Stack database in the cloud](https://developer.redis.com/create/rediscloud).\n1. Based on the language/framework you want to use, you will find the following client libraries:\n    - [Redis OM .NET (C#)](https://github.com/redis/redis-om-dotnet)\n        - Watch this [getting started video](https://www.youtube.com/watch?v=ZHPXKrJCYNA)\n        - Follow this [getting started guide](https://redis.io/docs/stack/get-started/tutorials/stack-dotnet/)\n    - [Redis OM Node (JS)](https://github.com/redis/redis-om-node)\n        - Watch this [getting started video](https://www.youtube.com/watch?v=KUfufrwpBkM)\n        - Follow this [getting started guide](https://redis.io/docs/stack/get-started/tutorials/stack-node/)\n    - [Redis OM Python](https://github.com/redis/redis-om-python)\n        - Watch this [getting started video](https://www.youtube.com/watch?v=PPT1FElAS84)\n        - Follow this [getting started guide](https://redis.io/docs/stack/get-started/tutorials/stack-python/)\n    - [Redis OM Spring (Java)](https://github.com/redis/redis-om-spring)\n        - Watch this [getting started video](https://www.youtube.com/watch?v=YhQX8pHy3hk)\n        - Follow this [getting started guide](https://redis.io/docs/stack/get-started/tutorials/stack-spring/)\n\nThe above videos and guides should be enough to get you started in your desired language/framework. From there you can expand and develop your app. Use the resources below to help guide you further:\n\n1. [Developer Hub](https://redis.info/devhub) - The main developer page for Redis, where you can find information on building using Redis with sample projects, guides, and tutorials.\n1. [Redis Stack getting started page](https://redis.io/docs/stack/) - Lists all the Redis Stack features. From there you can find relevant docs and tutorials for all the capabilities of Redis Stack.\n1. [Redis Rediscover](https://redis.com/rediscover/) - Provides use-cases for Redis as well as real-world examples and educational material\n1. [RedisInsight - Desktop GUI tool](https://redis.info/redisinsight) - Use this to connect to Redis to visually see the data. It also has a CLI inside it that lets you send Redis CLI commands. It also has a profiler so you can see commands that are run on your Redis instance in real-time\n1. Youtube Videos\n    - [Official Redis Youtube channel](https://redis.info/youtube)\n    - [Redis Stack videos](https://www.youtube.com/watch?v=LaiQFZ5bXaM\u0026list=PL83Wfqi-zYZFIQyTMUU6X7rPW2kVV-Ppb) - Help you get started modeling data, using Redis OM, and exploring Redis Stack\n    - [Redis Stack Real-Time Stock App](https://www.youtube.com/watch?v=mUNFvyrsl8Q) from Ahmad Bazzi\n    - [Build a Fullstack Next.js app](https://www.youtube.com/watch?v=DOIWQddRD5M) with Fireship.io\n    - [Microservices with Redis Course](https://www.youtube.com/watch?v=Cy9fAvsXGZA) by Scalable Scripts on freeCodeCamp\n\n### License\n```\nMIT\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpilotpirxie%2Frecommendation-redis","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpilotpirxie%2Frecommendation-redis","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpilotpirxie%2Frecommendation-redis/lists"}