Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use WHERE clause in Redis to query value

Tags:

redis

I am learning redis and I have a beginner question. I know that redis is all about keys! Is there any way to query/parse the value of a key for something specific?

Lets say I have keys and some json as values. e.g.

key1 = {"id":"1", "colour":"red}
key2 = {"id":"2", "colour":"green}
key3 = {"id":"3", "colour":"red}

How do I query for all "values (jsons) that have the colour=red?

select all values WHERE colour==red
like image 329
Gero Avatar asked Oct 10 '13 01:10

Gero


1 Answers

What you need is a reverse index on the colour field, i.e a mapping colour -> {keyA, ..., keyB}, e.g "red" -> {key1, key2}.

You can use a Redis set to maintain this index, as explained by Ohm:

A set in Redis is an unordered list [...] It's used internally by Ohm to keep track of the instances of each model and for generating and maintaining indexes.

See also this answer by Didier Spezia.

To sum up: store data the way you will query it.

Ohm example

Here is what happens with Ohm behind the scenes.

First declare your Ohm model, and index the colour attribute since you want to query it:

require "ohm"

class Doc < Ohm::Model
  attribute :colour
  index :colour
end

Then create some docs:

ruby> Doc.create(:colour => "red")
ruby> Doc.create(:colour => "green")
ruby> Doc.create(:colour => "red")

At this step inspect what Ohm stored in the related index:

redis> SMEMBERS "Doc:indices:colour:red"
1) "1"
2) "3"

Create one more red document:

ruby> Doc.create(:colour => "red")

Re-inspect the index:

redis> SMEMBERS "Doc:indices:colour:red"
1) "1"
2) "3"
3) "4"

The index has been updated to reflect the last record.

Now you can query your documents efficiently:

ruby> Doc.find(:colour => "red").each {|d| puts d.id}
1
3
4
like image 118
deltheil Avatar answered Oct 06 '22 00:10

deltheil