--- title: Redis pagination_prev: demos/desktop/index pagination_next: demos/local/index sidebar_custom_props: type: nosql --- Redis has 5 core data types: "String", List", "Set", "Sorted Set", and "Hash". Since the keys and values are limited to simple strings (and numbers), it is possible to store complete databases in a single worksheet. ![SheetJSRedis.xlsx](pathname:///nosql/sheetjsredis.png) ## Integration Details :::note [`SheetJSRedis.mjs`](pathname:///nosql/SheetJSRedis.mjs) exports the methods: - `redis_to_ws` creates a SheetJS worksheet by querying a redis client - `ws_to_redis` creates an array of query objects from the SheetJS worksheet ::: The first row holds the data type and the second row holds the property name. The "Exporting Data" snippets generate arrays of arrays that can be added to a worksheet using `sheet_add_aoa`. Since the data is column-oriented, the goal is to add the data starting in the first row of the column after the data: ```js function add_aoa_to_next_column(worksheet, aoa) { /* get range of worksheet */ const range = XLSX.utils.decode_range(worksheet["!ref"]) /* the origin to write new data will start in the column after the range */ const origin = XLSX.utils.encode_cell({ r: 0, // start on first row c: range.e.c + 1 // column after end }); /* add data */ XLSX.utils.sheet_add_aoa(worksheet, aoa, { origin }); } ``` The "Importing Data" snippets generate redis queries. The `ws_to_redis` function first generates an array of arrays with `sheet_to_json`: ```js const aoa = XLSX.utils.sheet_to_json(worksheet, { header: 1 }); ``` #### Strings Strings can be stored in a unified String table. The first column holds keys and the second column holds values: ``` XXX| A | B | ---+---------+-------+ 1 | Strings | | 2 | | | 3 | Hello | World | 4 | Sheet | JS | ``` The SheetJS array-of-arrays representation of the string table is an array of key/value pairs: ```js const aoa = ["Strings"]; aoa.length = 2; // [ "Strings", empty ] const keys = await client.KEYS("*"); for(let key of keys) { const type = await client.TYPE(key); // highlight-start if(type == "string") aoa.push([key, await client.GET(key)]); // highlight-end } ``` #### Lists Lists are unidimensional and can be stored in their own columns. ``` XXX| C | ---+---------+ 1 | List | 2 | List1 | 3 | List1V1 | 4 | List1V2 | ``` The SheetJS array-of-arrays representation of lists is a column of values. `LRANGE` returns a simple array of values. `sheet_add_aoa` interprets the result as one row. The code transposes the result with `values.map(v => [v])`. ```js const values = await client.LRANGE(key, 0, -1); const aoa = [ ["List"], [key] ].concat(values.map(v => [v])); ``` #### Sets Sets are unidimensional and can be stored in their own columns. ``` XXX| D | ---+-------+ 1 | Set | 2 | Set1 | 3 | Set1A | 4 | Set1B | ``` The SheetJS array-of-arrays representation of sets is a column of values. `SMEMBERS` returns a simple array of values. `sheet_add_aoa` interprets result as one row. The code transposes the result with `values.map(v => [v])`. ```js const values = await client.SMEMBERS(key); const aoa = [ ["Set"], [key] ].concat(values.map(v => [v])); ``` #### Sorted Sets Sorted Sets have an associated score which can be stored in the second column. ``` XXX| E | F | ---+---------+---+ 1 | Sorted | | 2 | ZSet1 | | 3 | Key1 | 1 | 4 | Key2 | 2 | ``` The SheetJS array-of-arrays representation is an array of key/score pairs. `ZRANGE_WITHSCORES` returns an array of objects which can be reshaped. ```js const values = await client.ZRANGE_WITHSCORES(key, 0, -1); const aoa = [ ["Sorted"], [key] ].concat(values.map(v => [v.value, v.score])); ``` #### Hashes Hashes are stored like the string table, with key and value columns in order. ``` XXX| G | H | ---+-------+-------+ 1 | Hash | | 2 | Hash1 | | 3 | Key1 | Val1 | 4 | Key2 | Val2 | ``` The SheetJS array-of-arrays representation is an array of key/value pairs. `HGETALL` returns a plain object which can be converted using `Object.entries`: ```js const values = await client.HGETALL(key); const aoa = [ ["Hash"], [key] ].concat(Object.entries(values)); ``` ## Complete Example :::note This demo was last tested on 2023 February 23 with Redis 7.0.8, Redis connector module 4.6.4 and NodeJS 18.14.2. ::: :::warning The most recent version of the `redis` node module does not work with most versions of NodeJS. It is "ESM-only", requiring NodeJS 18 or later. As a result, this demo also requires NodeJS version 18. Questions regarding the `redis` library and the decision to drop traditional NodeJS "CommonJS" module support should be directed to the Redis team. ::: 0) Set up and start a local Redis server. On Intel macOS: ```bash brew install redis@7.0.8 ``` 1) Download the following scripts: - [`SheetJSRedis.mjs`](pathname:///nosql/SheetJSRedis.mjs) - [`SheetJSRedisTest.mjs`](pathname:///nosql/SheetJSRedisTest.mjs) ```bash curl -LO https://docs.sheetjs.com/nosql/SheetJSRedis.mjs curl -LO https://docs.sheetjs.com/nosql/SheetJSRedisTest.mjs ``` 2) Install dependencies and run: ```bash npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz redis@4.6.4 node SheetJSRedisTest.mjs ``` Inspect the output and compare with the data in `SheetJSRedisTest.mjs`. Open `SheetJSRedis.xlsx` and verify the columns have the correct data