Skip to content

Instantly share code, notes, and snippets.

@ckdake
Created October 14, 2011 19:47
Show Gist options
  • Save ckdake/1288116 to your computer and use it in GitHub Desktop.
Save ckdake/1288116 to your computer and use it in GitHub Desktop.
Scaling Search
# in the controller
def index
# Put the connections in a hash here so it's one DB query
# instead of 10
@connections = Hash.new
User.where(
id: current_user.cached_connections_ids
).each do |user|
@connections[user.id] = user
end
end
def allowed_connections_ids(force = false)
Rails.cache.fetch("uaci-#{self.id}",
expires_in: 7.days,
force: force
) do
self.allowed_connections.map(&:id)
end
end
# This should be run out of band as it's very expensive to compute
def update_allowed_connections_ids(force = false)
# Cache key is short for 'user connections count'
Rails.cache.write(
"uaci-#{self.id}",
self.allowed_connections.map(&:id),
force: force
)
end
# Use this for accessing the allowed ids instead
# of directly accessing it (performance)
def allowed_connections_ids(force = false)
# If we're forcing, run the expensive computation in-band
if force
self.update_allowed_connections_ids(true)
end
# Try getting the answer from the cache
cached = Rails.cache.fetch("ucc-#{id}")
# If we don't have it, schedule and update of this and run
# it in the background, and just return 0 for now.
if cached.nil?
cached = 0
self.delay.update_allowed_connections_ids
end
cached
end
searchable do
text :name
text :location
integer :id
end
def connections_ids_matching(params, force = false)
# the id set for permission matching must be smaller than
# the limitations of solr's OR clause: 1024
self.allowed_connections_ids.each_slice(1024).flat_map { |id_pool_set|
User.search_ids do
fulltext params[:search_text] do
boost_fields name: 2, location: 0.5
end
with :id, id_pool_set
paginate per_page: SOLR_MAX_OR_CLAUSES
end
}
end
web: bundle exec rails server thin -p $PORT
worker: bundle exec rake jobs:work
memcached: bundle exec memcached -m 64
solr: bundle exec rake sunspot:solr:run
# in the view
ul
- @connection_ids.each do |connection_id|
- if connection = @connections[connection_id]
li= connection.to_s
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment