order of fields in HMSET

283 views
Skip to first unread message

usergoodvery

unread,
Mar 3, 2016, 6:28:02 AM3/3/16
to Redis DB
Hi,
Is there a way to control the order in which fields are returned from a HMSET command? It seems every time I add a new field-value pair to a hash set, the order in the which the entire set returns (using HVALS) changes, messing up my array indexing. I have to go back and remap the fields again to the new order (I use hiredis). 

What are the rules for how the order is determined? It doesn't seem the order in which fields are input using HMSET is preserved.

If I have a fixed number of fields in that I use for for all keys set using HMSET, am I guaranteed that for that set the order will always be the same?

Regards,


Itamar Haber

unread,
Mar 3, 2016, 6:42:19 AM3/3/16
to Redis DB
Hi user, very good to meet you!

The order of fields in a Hash is for all intents and purposes random. If require order, sort the response in the application or use a different data structure (e.g. a Sorted Set).

--
You received this message because you are subscribed to the Google Groups "Redis DB" group.
To unsubscribe from this group and stop receiving emails from it, send an email to redis-db+u...@googlegroups.com.
To post to this group, send email to redi...@googlegroups.com.
Visit this group at https://groups.google.com/group/redis-db.
For more options, visit https://groups.google.com/d/optout.



--

Itamar Haber | Chief Developer Advocate
Redis Watch Newsletter | &&(curat||edit||janit||)
Redis Labs | ~ of Redis

Mobile: +972 (54) 567 9692
Email: ita...@redislabs.com
Twitter: @itamarhaber
Skype: itamar.haber

Blog  |  Twitter  |  LinkedIn

 #RedisConf

Jan-Erik Rediger

unread,
Mar 3, 2016, 6:42:58 AM3/3/16
to redi...@googlegroups.com
Hashes do not have a defined order. You cannot rely on any order of
values returned by HVALS.
If you need explicit mapping use HGETALL to know what values correspond
to what vield or use HMGET to explicitely define the fields you want to
fetch.

Greg Andrews

unread,
Mar 3, 2016, 3:50:22 PM3/3/16
to redi...@googlegroups.com
Hashes do not guarantee the order in which the fields will appear when you read them.  This is actually a *good* thing.  It makes writing and reading the data faster.  Much faster.  If Redis had to perform work to keep track of the order of fields and arrange them in that order every time, it would make the writes and reads slower.

This is at the very heart of the popularity of non-SQL data stores (like Redis) over the past 6-8 years.  SQL got too slow for high-volume sites, so data store software was invented that was designed around hash functions.  Hash functions trade away the guarantee that elements will be returned in a particular order, but they gain great speed.

  -Greg

usergoodvery

unread,
Mar 4, 2016, 3:38:13 AM3/4/16
to Redis DB, jan...@fnordig.de
Hi,
Thanks folks. Relying on HGETALL and reading individual field names to determine what the value pertains to is high overhead... if the order is deterministic I just index straight into the field in the returned array, which is what i am doing now, expect the indexing changes if I add new filed-value pairs. As I I said I can remap those every time i add new field so long as the set will always return in that order thereafter (until I put a new field).
Your other suggestion might be good fall back ie explicitly state the fields. You seem to be suggesting that will always return in the order specified in the command... I think that is much more palatable than HGETALL route.

I can't get my head around the argument that it is more efficient for redis to return fields in random order, but I am not close enough to the internals of redis. 

AlexanderB

unread,
Mar 4, 2016, 1:36:10 PM3/4/16
to Redis DB, jan...@fnordig.de
It may be inconsistent between Redis releases, operating system updates, and on different machines, so I'd be careful about that. Redis makes no guarantee about the order, so it's very likely that somewhere along the lines this could break for you. 

One thing you might want to try is to just store all of the values together as one big compound string. This may or might not work for your use case though so you'll have to give it some thought. 
The basic idea would be to store things in a key with a series of values with a separator character. I.e. "value1:value2:value3" you could then do the splitting in your client app, or write a lua script to pull out the value, do the splitting on the server, and send it back in the same form as HGETALL. 

Another option if that doesn't work, would be to just pipeline or lua script a series of individual HGETS so that you'll pull out all the values in a deterministic order. If you go with the lua script approach, you'd be able to hard code the field names into the script, and you wouldn't be paying much of any extra network overhead for the extra commands. If you're current bottleneck is network IO rather than cpu, this approach might be not have any noticeable performance differences from your current approach. 

Itamar Haber

unread,
Mar 5, 2016, 9:37:43 AM3/5/16
to Redis DB, Jan-Erik Rediger
It may be inconsistent between Redis releases, operating system updates, and on different machines

Even more than that AFAIK - it may be inconsistent between two calls to the same database.


Reply all
Reply to author
Forward
0 new messages