-
-
Save alanstevens/3c2810aa9d0b6884c187 to your computer and use it in GitHub Desktop.
def find_associate_common user_ids | |
# search types | |
@selected_types = [] | |
@selected_types << 'User'.constantize | |
# default fields to search | |
@default_assoc_search_fields = ['last_name_text', 'first_name_text', 'middle_name_text', 'email_text', 'city_region_text', 'country_text'] | |
@search_all_profile = params[:search_all_profile] ||= false | |
# selected content search type | |
@selected_search_type = params[:stype].present? ? params[:stype] : 'anyword' | |
@selected_specialty_search_type = params[:sptype].present? ? params[:sptype] : 'anyspec' | |
# include professional bio fields | |
@include_professional_bio = params[:cpbio].present? ? params[:cpbio] : 'false' | |
# include personal bio fields | |
@include_personal_bio = params[:cpbio].present? ? params[:cpbio] : 'false' | |
# set up pagination | |
cur_page = params[:page] ||= 1 | |
per_page = params[:per_page] ||= 10 | |
# setup the search type and value... | |
@q = params[:assoc_keywords] ||= nil | |
qry_empty = @q.nil? || @q.blank? || @q.empty? | |
# 02-JUL-2012 - downcase the search string. For some reason lucene won't find "Finn" as part of a "standard" query | |
# but does find "finn". | |
qry = @q.downcase | |
qry = qry + "*" if qry.size < 5 | |
if !qry.nil? | |
qry.strip! | |
logger.debug "qry(1): #{qry}" | |
case @selected_search_type | |
when 'allwords' | |
qry = "(#{qry.gsub(' ', ' AND ')})" | |
when 'exact' | |
qry = "\"#{qry}\"" | |
else | |
# defaults to any words... | |
end | |
end | |
logger.debug "qry(2): #{qry}" | |
qry = "( #{qry} ) AND " if !qry.blank? | |
qry += ' !agent_categories_text:"Alternate Contact" ' | |
# check for specialties | |
aspec_qry = "" | |
aspec_op = @selected_specialty_search_type == 'anyspec' ? " OR " : " AND " | |
qt_param = "standard" | |
if params[:search_for_specialties] == '1' && params[:agent_specialties].present? && params[:agent_specialties][:specialty_id].present? | |
params[:agent_specialties][:specialty_id].each do |spec_id| | |
aspec_qry += "specialty_tags_text:\"#{AgentSpecialtyList[spec_id.to_i].name}\" #{aspec_op} " | |
# still trying to figure out when / how to use dismax | |
# it seems that when we're searching against the main "text" (e.g., keywords) | |
# and are also searching specific fields for content (e.g., specialties) then | |
# dismax is the way to go. otherwise, leave the qt_param empty so solr / lucene | |
# use the "standard" search parser | |
qt_param = "standard" if qt_param == "" && !qry_empty | |
qry_empty = false | |
end | |
aspec_qry.chomp!("#{aspec_op} ").strip! | |
aspec_qry = " ( #{aspec_qry} )" unless aspec_qry == "" | |
end | |
qry += " AND " if qry != "" && aspec_qry != "" | |
qry += aspec_qry | |
logger.debug "qry: #{qry}" | |
logger.debug "qry: #{qry}" | |
# check for market longitude / latitutde | |
# run the search with paginated results | |
@results = Sunspot.search(@selected_types) do | |
# setup a full text query | |
fulltext qry | |
# adjust the solr parameters as needed | |
adjust_solr_params do |param| | |
# use the qt param vs the deftype param - not sure why but solr's dismax parser works better with the :qt option | |
param[:defType] = '' | |
param[:qt] = qt_param if qt_param != "" | |
param[:sort] = 'score desc, last_name_text asc' | |
#param[:qt] = 'dismax' | |
#param[:qt] = 'standard' | |
#param[:qf] << " content_text" | |
end | |
# setup pagination | |
paginate :page => cur_page, :per_page => per_page | |
end unless qry_empty | |
end |
So the answer depends on how the User
model is configured for indexing via sunspot. You have to make sure you have the id
field included. If it's not included, then it's possible but sunspot doesn't make it very easy. Something like this would make sure it's included, assuming standard integer IDs:
class User < ActiveRecord::Base
# yada yada yada
searchable do
integer :id
text :last_name, :first_name, :email
# other fields, etc
end
end
If you have the id
field indexed, and if you pass a collection of user IDs into the method (e.g. user_ids
is [1,2,3,4]
) then you can update your Sunspot search to the following:
@results = Sunspot.search(@selected_types) do
# setup a full text query
fulltext qry
without(:id, user_ids)
# adjust the solr parameters as needed
adjust_solr_params do |param|
# use the qt param vs the deftype param - not sure why but solr's dismax parser works better with the :qt option
param[:defType] = ''
param[:qt] = qt_param if qt_param != ""
param[:sort] = 'score desc, last_name_text asc'
#param[:qt] = 'dismax'
#param[:qt] = 'standard'
#param[:qf] << " content_text"
end
# setup pagination
paginate :page => cur_page, :per_page => per_page
end unless qry_empty
The "without" API does what the stackoverflow post suggests -- it adds the -
exclusion to the fq
portion of the query. I verified this in my app that uses sunspot and solr, and I was able to exclude things based on ID using this API.
It also might depend on what version of the sunspot gem you are using -- not sure when the without
API was added.
IF, like in my project by default, you don't specify the config to index the id
, then the id
value put into solr is a string like "User 523" -- {class name} {id}
. Using the solr admin web interface I was able to issue the right query and it excluded things, but the sunspot ruby API validates field names and didn't like me specifying id
when it wasn't in the list defined on the model.
Hope that helps, let me know what you find out.
You can enable solr debugging output in the sunspot results like this:
@results = Sunspot.search do
fulltext qry
adjust_solr_params do |param|
param['debugQuery'] = 'on'
# ...
end
end
And you can access it in the result with a hack like this: @results.try(:instance_variable_get, :@solr_result).try(:[], 'debug')
That will yield a hash with keys like querystring
, timing
, and explain
(I personally love explain
as it makes it really helpful to determine why results came back the way they did, which can be a common client/user question.)
You can also see the XML in the results, I believe -- not sure the debug key to use.
I would like to pass a collection of user ids and have those users filtered from the query results.
I found this: http://stackoverflow.com/questions/11855830/how-to-do-not-in-query-in-solr
which suggests that it can be done using a filter query but I can't find a way to use it here.