Recommendation system
Tags: redishackathon
Published: 2022-08-28 10:04:00

### Overview of My Submission

![Project logo](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kf8cthjn8yasqvty206p.png)

#### Recommendation System

Open 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.

## Features
* Use tag score and Jaccard index
* Content-based filtering
* Event-driven powered engine
* Naive exploration of new tags
* Suitable for product and content recommendation
* Fine-tuning of tag weights
* Minimalist and lightweight
* Written in TypeScript and Node.js


## How it works

### How the data is stored:
* Actors are stored in Redis as simple ``String`` keys with create date ``timestamps`` as value.
* Items are ``Set`` type with ``tags`` as members. The item may have multiple tags.
* Events are ``String`` type with ``actorId:id:tag:timestamp:ttl`` and an expire attribute set to ensure freshness of recommendations.

### How the data is accessed:
* Get the actor with events
  * Check if the actor exists with ``EXISTS actor:${id}``
  * Get all user events with ``SCAN ${loop cursor} MATCH actor:${id}``
* Delete a single actor
  * Scan for each related to actor key ``SCAN ${loop cursor} MATCH actor:${id}*``
  * For each key delete with ``DEL ${key}``
* Add a single actor
  * Scan for each related to actor key ``SCAN ${loop cursor} MATCH actor:${id}*``
  * For each key delete with ``DEL ${key}``
  * Add new actor with ``SET actor:${id} ${Date.now().toString()}``
* Add a single event
  * Check if actor exists if flag is set using ``EXISTS actor:${id}``
  * Add event with ``SET actor:${id}:${tag}:${date}:${ttl} ${score}``
  * If ``TTL`` has been provided, set expiration for event with ``EXPIRE actor:${id}:${tag}:${date}:${ttl} ${ttl}``
* Get all items with tags
  * Get all items with ``SCAN ${loop cursor} MATCH item:*``
  * For each item get all tags with ``SMEMBERS ${itemKey}``
* Get a single item with tags
  * Get all tags of item with ``SMEMBERS item:${id}``
* Delete single item
  * Call with ``DEL item:${id}``
* Add a single item
  * Check if item already exists ``EXISTS item:${id}``
  * If so, then remove ``DEL item:${id}``
  * And add item with tags ``SADD item:${id} ${tags}``

{% github pilotpirxie/recommendation %}

### Video - Demo of film recommendations 
{% youtube https://www.youtube.com/watch?v=_m1BandnVsQ %}

### Submission Category: 
Minimalism Magicians

Replaces time series database for high volume input of actor (e.g. user) events and OLAP operations to calculate recommendations. Have in mind the time limitation of hackathon so take this statement with a pinch of salt ;)

### Language Used
TypeScript

### Link to Code

[https://github.com/pilotpirxie/recommendation](https://github.com/pilotpirxie/recommendation)

### Additional Resources / Info

![Architecture](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pm0k017kayjds0lq1a35.png)

### Collaborators

{% user meatboy %}

- - - 

* _Check out [Redis OM](https://redis.io/docs/stack/get-started/clients/#high-level-client-libraries), client libraries for working with Redis as a multi-model database._
* _Use [RedisInsight](https://redis.info/redisinsight) to visualize your data in Redis._
* _Sign up for a [free Redis database](https://redis.info/try-free-dev-to)._