2

I have a Redis database with the following structure

Redis estructure

And, I want get in one query only the first level keys. I mean: [EB, HY, LV, LW, MB, NV].

I have thought in keys * which return every key in database. After that, I would loop over all them, split keys and count the appearances of each. But it requires code, and I want get the wished result in one line, if possible, of course.

Someone know how to help me? Thanks a lot.

Luis González
  • 3,199
  • 26
  • 43
  • [EB, HY, ...] are set of data? Keys * only return first level of data. Question : Where are you using to display this tree – khanou Dec 01 '15 at 11:32
  • `keys *` return all keys: `EB:0V:..., EB:400V:...., HY:0V:..., HY:400V:...` and I only want `EB, MB, HY,...` without looping all the keys and manually filtering. I am using Redis Desktop Manager http://redisdesktop.com/ – Luis González Dec 01 '15 at 11:37
  • yeah, you need to write some code. – Sergio Tulentsev Dec 01 '15 at 12:20

2 Answers2

2

And, I want get in one query only the first level keys. I mean: [EB, HY, LV, LW, MB, NV].

These "keys" don't exist. They are creation of your redis GUI. Redis itself doesn't know about them. As you noted, your real keys are in this form:

EB:0V:...
EB:400V:....
HY:0V:...
HY:400V:...

There is no command in redis that will return part of a key name. This is to be handled in your app. Fetch full key names, split on colon, aggregate.

Sergio Tulentsev
  • 226,338
  • 43
  • 373
  • 367
2

First, as Sergio Tulentsev mentioned, your GUI is interpreting colons as performing namespacing. Redis itself, does not do this. There's good discussion of the role of colons in Redis in this SO question.

That said, you will need to write code to do this. How that code is written depends on what environment you plan on doing this in and what your speed and consistency requirements are.

If you just want to do this locally or on dev to get a basic idea of what top level keys you have, you can just call KEYS * through your backend language Redis client of choice and then iterate through what's returned to find all top level namespaces. An example in Python using redis-py:

import redis
r = redis.Redis(host='localhost', port=6379, db=0)
top_level_namespaces = set([item.split(':')[0] for item in r.keys('*')])

If you want to do this in production, you have to keep in mind that KEYS * is very, very slow and will block the redis db til it finishes. If you're OK with that, you can write a quick LUA script with the same logic as my Python example above so that the logic is run on the Redis server and you don't need to waste network time transferring all keys back to your app server.

If KEYS(*) is too slow for your use case, and consistency is not super important, you can use SCAN instead and iterate over the results.

If KEYS(*) is too slow and consistency is very important, the best thing you can do is maintain an auxiliary set of your top level namespaces in your app as application logic and just SMEMBERS to retrieve them when needed. Writing and maintaining the application logic will be annoying, but this will be the fastest and most durable approach.

Community
  • 1
  • 1
Eli
  • 36,793
  • 40
  • 144
  • 207