June 14, 12 Structure aware: it knows how to index fields in JSON, XML, and Erlang terms, besides plain text That it only indexes on save means that if you have to re-index, it has to scan each value
Favorite Thursday, June 14, 12 You can (and for my HIPAA-sensitive project, we do) index at-rest encrypted data this way One re-indexing caveat: you have to re-specify indexes when you update a record
14, 12 You can (and for my HIPAA-sensitive project, we do) index at-rest encrypted data this way One re-indexing caveat: you have to re-specify indexes when you update a record
14, 12 Let’s start with a zombie-themed example. There’s a bunch of brains wandering around, they get eaten by zombies. We want to easily query a few things about them.
eaten_at size Brains Thursday, June 14, 12 We want to find a given brain by owner (i.e. who got their brain eaten), the zombie that ate it, find what brains a zombie ate where, find what brains a zombie ate on a given day, and what days a given hideout gets raided on.
true property :zombie_key, String, index: true property :hideout_id, Integer property :eaten_at, Time one :owner, using: :stored_key one :zombie, using: :stored_key index :zombie_hideout, String do "#{zombie_key}-#{hideout_id}" end index :zombie_eaten, String do "#{zombie_key}-#{eaten_at}" end index :hideout_eaten, String do owner_id zombie_id hideout_id eaten_at size Brains Query Design Thursday, June 14, 12 For the sake of discussion, Hideouts are stored with ActiveRecord
true property :zombie_key, String, index: true property :hideout_id, Integer property :eaten_at, Time one :owner, using: :stored_key one :zombie, using: :stored_key index :zombie_hideout, String do "#{zombie_key}-#{hideout_id}" end index :zombie_eaten, String do "#{zombie_key}-#{eaten_at}" end index :hideout_eaten, String do "#{hideout_id}-#{eaten_at}" end def hideout Hideout.find hideout_id end def hideout=(hideout) owner_id zombie_id hideout_id eaten_at size Brains Query Design Thursday, June 14, 12 Cardinality is important in multi-field indexes. If we wanted to group by zombie_key, these would be fine
"#{zombie_key}-#{eaten_at}" end index :hideout_eaten, String do "#{hideout_id}-#{eaten_at}" end def hideout Hideout.find hideout_id end def hideout=(hideout) self.hideout_id = hideout.id end end owner_id zombie_id hideout_id eaten_at size Brains Query Design Thursday, June 14, 12 For the sake of discussion, Hideouts are stored with ActiveRecord
#=> [<Brain:Xo0FJfY8yDHcY5tqQ4icHFL8Vkp owner_key="…" zombie_key="…" hideout_id=5 eaten_at=2012-06-14 03:39:30 UTC>] Brain.find_by_index 'hideout_eaten', ("5-00000000001339645100".."5-0000000000133 9645150") #=> [] owner_id zombie_id hideout_id eaten_at size Brains Query Design Thursday, June 14, 12 We use a range query to find all the brains that got eaten at hideout 5 between 100 and 200, and we see that 170 counts
Brain.find_by_index 'hideout_eaten', ("5-00000000001339645100".."5-0000000000133 9645150") #=> [] owner_id zombie_id hideout_id eaten_at size Brains Query Design Thursday, June 14, 12 And there wasn’t anything between 100 and 150; 170 is outside of that range.