55

I'm wondering if there's a way to check if a key already exists in a redis list?

I can't use a set because I don't want to enforce uniqueness, but I do want to be able to check if the string is actually there.

Thanks.

Dan Atkinson
  • 11,391
  • 14
  • 81
  • 114
Reu
  • 1,257
  • 3
  • 15
  • 30

5 Answers5

71

Your options are as follows:

  1. Using LREM and replacing it if it was found.
  2. Maintaining a separate SET in conjunction with your LIST
  3. Looping through the LIST until you find the item or reach the end.

Redis lists are implemented as a http://en.wikipedia.org/wiki/Linked_list, hence the limitations.

I think your best option is maintaining a duplicate SET. This is what I tend to do. Just think of it as an extra index. Regardless, make sure your actions are atomic with MULTI-EXEC or Lua scripts.

Fritzy
  • 1,014
  • 7
  • 7
  • @fritzy would it be possible elaborate more about how to implement the SET/LIST or point me somewhere, thanks. – Karim Tarek Aug 21 '16 at 16:45
  • Since both the LREM and SREM are O(N) then it is probably better to not have a separate set (unless, of course, you plan to delete the entire set rather than item-by-item). –  Mar 17 '17 at 20:18
  • Use `SET` indeed. – Sergey Belash Jun 05 '17 at 20:16
  • @kristen `LREM` is O(N) where N is the length of the list, but `SREM` complexity for 1 element is O(1) since N is the number of members to be removed. And SISMEMBER is always O(1). – Sergey Belash Jun 05 '17 at 20:25
32

Lists allow duplicates but do not provide a simple way to check for existence and as @Fritzy advised, you either need to:

  • Make multiple operations (remove then add again if found during removal) for simple checks = Cost in time
  • Maintain a separate set = Cost in memory

I am surprised no one advised you to use either a Hash Table or a Sorted Set which combine advantages of allowing duplicity (by storing the number of elements as value - Hash Table, or score - Sorted Set) and indexing members by nature of a hash table/set.


Hash Table

To check for a key existence, use HEXISTS for a specific field which returns 0 if the specified member does not exist. You could also use the HGETcommand. It returns a nil answer if the specified member does not exist.

To add a new member, simply use HINCRBY which will either update the value (ie the number of elements with the member name) or create a new member if it does not exist.


Sorted Set

To check for a key existence, use either one of the three following commands:

  • ZSCORE
  • ZRANK
  • ZREVRANK

They return a nil answer if the specified member does not exist.

To add a new member, simply use ZINCRBY which will either update the score (ie the number of elements with the member name) or create a new member if it does not exist.


To sum up: Sorted Sets or Hash Tables allow you to make all the operations with your requirements with a single command.

Bernard Rosset
  • 4,523
  • 6
  • 27
  • 29
  • However, if someone uses a sorted set, there's no way to tell where exactly are these multiple instances of a value present in the list. If I have the value "Hello World" at arbitrary locations in a list, then just storing the number of times it appears wouldn't help me locate the surrounding elements of those instances. – Anuraag Vaidya Jul 17 '16 at 14:50
  • @AnuraagVaidya This is another problem, not relevant in the current context of replying to the question having been asked. – Bernard Rosset Mar 27 '17 at 09:08
17

You can also use LPOS.

When the item exists it returns a number indicating the position:

LPOS mylist myitem
3

When not it returns nill:

LPOS mylist myitem_which_do_not_exits
(nil)

Ravexina
  • 2,406
  • 2
  • 25
  • 41
16

I am surprised that no one mentioned the set, which perfectly solved the question.
Using the sismember key value in set, it checks if the value is a member of the key.
Here is the example:

redis 127.0.0.1:6379> SADD myset1 "hello"
(integer) 1
redis 127.0.0.1:6379> SISMEMBER myset1 "hello"
(integer) 1
redis 127.0.0.1:6379> SISMEMBER myset1 "world"
(integer) 0
yinhaomin
  • 327
  • 2
  • 4
6

No, there is no way to check if a redis list contains a given value. See Redis list commands for reference.

I guess you could use LREM to (try to) remove the value, and check the return value to see if it was removed. But then you would have to put it back in, and this seems iffy. There is probably some better solution to your problem - what are you trying to accomplish?

Linus Thiel
  • 38,647
  • 9
  • 109
  • 104
  • 1
    hi linus, i guess he is asking if a "key" exists or not. not a given value as you assume – zotherstupidguy Sep 08 '12 at 17:05
  • @babydudecoder He said he wants to check a key already exists in a redis list. i think his key is a value of redis list. – Hieu Le Sep 25 '14 at 04:17
  • @Harry It seems like in most cases he could substitute the list for an `hset` - and use `setnx`, that's not quite the same as having a real list of course, but hash tables are generally faster lookups anyways. – user3467349 Feb 03 '15 at 19:33