docs.sheetjs.com/docz/docs/03-demos/07-data/26-redis.md
2023-05-11 02:17:10 -04:00

5.6 KiB

title pagination_prev pagination_next sidebar_custom_props
Redis demos/desktop/index demos/local/index
type
nosql

import current from '/version.js'; import CodeBlock from '@theme/CodeBlock';

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

Integration Details

:::note

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:

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:

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:

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]).

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]).

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.

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:

const values = await client.HGETALL(key);
const aoa = [ ["Hash"], [key] ].concat(Object.entries(values));

Complete Example

:::note

This demo was last tested on 2023 May 11 with Redis 7.0.11, Redis connector module 4.6.6 and NodeJS 20.1.0.

:::

:::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 or later.

:::

  1. Set up and start a local Redis server.

:::note

This demo was last tested on Intel macOS. Redis was installed with:

brew install redis@7.0.11

The following command started the server process:

/usr/local/opt/redis/bin/redis-server /usr/local/etc/redis.conf

:::

  1. Download the following scripts:
curl -LO https://docs.sheetjs.com/nosql/SheetJSRedis.mjs
curl -LO https://docs.sheetjs.com/nosql/SheetJSRedisTest.mjs
  1. Install dependencies:

{\ npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz redis@4.6.6}

  1. Run the test script:
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