I was reading about how secondary indexes work in redis.
Some people think that well hey, redis is a key-value store isn’t it? So why would someone wanna query or filter by anything other the key itself? Whatever it is that you want to query, put it in the key itself and match the keys with the MATCH keyword. I’ve read this opinion on some stackoverflow answers.
But suppose you are storing data about users, which is a good case to store data using redis hash, and if you want to query users based on the values of certain key(s) in the user hash. That’s what this article is about.
Search by one numerical key? No problem. Whenever you insert a new hash or update an hash field by which you want to query, update a sorted set with key being the same as the user’s hash key and score being equal to the numerical field. Wrap both the operations in a MULTI/EXEC transaction.
Search by multiple fields using ZINTERSTORE. ZINTERSTORE finds intersection of multiple sorted sets in redis, and creates a new sorted set with the result. What about the score, what happens to that? What does it do with the score of the elements which are common across the sets? It adds up the respective scores and then assigns the sum of the score as the new score in the result set.
You can use WEIGHTS parameter, which will in turn tell redis to multiply the original score in the set with the specified weight value and this process repeats for every input set, and only after applying the weights is the sum calculated which is set as the final score.
You can use this property for querying by multiple fields.
Choosing the weights will depend on the range of the fields that you are about to query. Choose the weights in such a manner that you end up with a unique end-result score for that element, so that there are no collisions.
And then you can get the hash keys by using ZRANGE and the respective score. Done.
Note : Scores in redis can range from -9007199254740992 and 9007199254740992.