Reputation: 1183
Given that I want to find 20 relevant results how would I go about boosting the first criteria inside any_of (with(:id).any_of(co_author_ids)) so that if there are 20 results which match said criteria it will return as opposed to trying to match based on the second criteria?
@solr_search = User.solr_search do
paginate(:per_page => 20)
with(:has_email, true)
any_of do
with(:id).any_of(co_author_ids)
with(:hospitals_id).any_of(hopital_ids)
end
end
Initially I didn't think boosting was necessary as I figured any_of would have a cascading effect but it does not appear to work like that. I know who to do query time boosting on keywords and fulltext searches but have been unable to get it working with with() methods.
Upvotes: 4
Views: 776
Reputation: 3656
since co_author_ids is a multivalued key , i have enough reasons to believe that there is no way to achieve that. although with single value keys it is possible to achive this cascading effect by using solr sort using function query. http://wiki.apache.org/solr/FunctionQuery#Sort_By_Function aong with the adjust_solr-params http://sunspot.github.io/docs/Sunspot/DSL/Adjustable.html
Example: suppose you have query like this:
@solr_search = User.solr_search do
paginate(:per_page => 20)
with(:has_email, true)
any_of do
with(:id,author_id) #assuming author id is a solr index
with(:hospitals_id).any_of(hopital_ids)
end
end
and now in this case you want to have a cascading effect and want to give more preference to exact matches with author_id you can do this way
@solr_search = User.solr_search do
paginate(:per_page => 20)
with(:has_email, true)
any_of do
with(:id,author_id) #assuming author id is a solr index
with(:hospitals_id).any_of(hopital_ids)
end
adjust_solr_params do |p|
p["sort"] = "if(author_id_i = #{id},1,0) desc" #note author_id_i solr eq of author_id
end
end
so this will sort on the basis of the value of if(author_id_i = #{id},1,0) and in return will put all the records with auhtor_id as same of the user on top.
i somehow was getting problems using IF function so i instead used (practicaaly both of them are same):
@solr_search = User.solr_search do
paginate(:per_page => 20)
with(:has_email, true)
any_of do
with(:id,author_id) #assuming author id is a solr index
with(:hospitals_id).any_of(hopital_ids)
end
adjust_solr_params do |p|
p[:sort] = "min(abs(sub(author_id_i,#{id})),1) asc"
end
end
i stumbled upon this also http://wiki.apache.org/solr/SpatialSearch while looking for a solution for this and if you want to sort by distance you can do something like:
@solr_search = User.solr_search do
paginate(:per_page => 20)
with(:has_email, true)
any_of do
with(:id,author_id) #assuming author id is a solr index
with(:hospitals_id).any_of(hopital_ids)
end
adjust_solr_params do |p|
p[:pt] = "#{latitude_of_your_interest},#{longitude_of_your_interest}"
p[:sfield] = :author_location #your solr index which stores location of the author
p[:sort] = "geodist() asc"
end
end
overall i would say you can do a lot of cool things with p["sort"] but in this particular case it cant be done( imho) because it being a multivalued field ex: Using multivalued field in map function Solr function query that operates on count of multivalued field
I wish they could just provide a include function for multivalued field and we can just write
p["sort"] ="if(include(co_authors_ids,#{id}), 1, 0) desc"
but as of now its not possible(again imho).
Upvotes: 5