Home Tips about Hash commands
Post
Cancel

Tips about Hash commands

When to use hash?

Store key - value entity.
It’s similar row in traditional database

Reasons to use hashes

  • The row has many attributes
  • A collection of records have to be sorted many different ways.
  • Often need to be accessed single row at a time

EX) user, item, session entities.

Don’t use hashes when

  • Thr row has few attributes
  • Row is only for counting or enforcing uniqueness.
  • Used only for creating relations between different entity
  • Time series data

EX) views, like, bids

Don’t use null and undefined, nested object

Unlike, traditional database. Redis doesn’t allow insert null or undefined as value.

TL;DR;

Don’t use nested object and null, undefined as it is.

I’ll show the example.
This code may lead to error.

Example

1
2
3
4
5
6
7
8
9
10
11
12
const run = async (): Promise<void> => {
  await client.hSet('car', {
    color: 'red',
    year: 1950,
    engine: { cylindar: 8 },
    owner: null,
    service: undefined
  });
  const car = await client.hGetAll('car');
  console.dir(car);
};
run();

Error

TypeError: Cannot read properties of null (reading 'toString')
TypeError: Cannot read properties of undefined (reading 'toString')

Why error occurs?

In HSET, redis client internally .toString() method is called before inserting value regardless of input data type. when trying null.toString() not allowed.

Also, nested object value is converted to [Object object]

1
2
3
4
5
{
  color: 'red',
  year: '1950',
  engine: '[object Object]'
}

How to resolve it?

Use empty string instead of null or undefined.

1
2
3
4
5
6
7
8
9
10
11
12
const run = async (): Promise<void> => {
  await client.hSet('car', {
    color: 'red',
    year: 1950,
    engine: { cylindar: 8 },
    owner: null || '',
    service: undefined || ''
  });
  const car = await client.hGetAll('car');
  console.dir(car);
};
run();

HGETALL has gatcha

Be careful using HGETALL on your application. Maybe you are to expect null or undefined if key doesn’t exists. However, redis return {} (I call it empty object)

Let me show you example.

example code

1
2
3
4
5
6
7
8
9
const run = async (): Promise<void> => {
  const car = await client.hGetAll('car#noteixst');
  if (!car) { // This code is not executed
    console.log("car doesn't exist");
    return;
  }
  console.dir(car);
};
run();

result

{}

This default behavior is different to traditional database.

How to resolve it?

You should use custom empty object check method.

1
2
3
4
5
6
7
8
9
10
11
12
13
const run = async (): Promise<void> => {
  const car = await client.hGetAll('car#noteixst');
  if (isEmptyObject(car)) {
    console.log("car doesn't exist");
    return;
  }
  console.dir(car);
};
run();

function isEmptyObject(obj: object) {
  return Object.keys(obj).length === 0;
}

result

car doesn't exist
This post is licensed under CC BY 4.0 by the author.

Redis multi key and range operation

Serialize and Deserialize

Trending Tags