Question

I'm a novice to using sunspot/solr and have stumbled upon an issue in a bigger project where it's already being used in a pretty heavy way. What I need to do is find a way to sort/boost the score of a result based on whether it has a value in a multi valued field. To make it more clear lets suppose I have the following setup:

searchable do
  integer user_ids
  integer unread_by_user_ids
end

I want to get a list of all the documents for a given user with the results being ordered by whether the user has read the document already or not. Also I need to mention that I page the results, so ordering them after the solr search is out of the question. I've tried looking at similar questions like the one here: Rails Sunsport/Solr: Ordering on multiple-value field , but since there are no actual answers, I thought I'd try my luck posting a new one. From what I've been reading it seems to me that there is no method to do this and the best course of action would be to do 2 queries, one for the unread items and one for the read items needed to complete a page of results if any are needed and concatenate the results. Still, I wanted to make sure there is no better way of doing this first. Any help/advice is appreciated.

Was it helpful?

Solution

I finally solved this issue by using dynamic fields. Here's what the searchable declaration looks like:

searchable do
  integer user_ids
  dynamic_boolean :document_read_status do
    user_ids = get_all_user_ids
    unread_user_ids = get_all_unread_user_ids
    user_ids.inject({}) do |hash, user_id|
      hash.merge(:"unread_by_#{user_id}" => unread_user_ids.include?(user_id))
    end
  end
end

and the actual search looks like this:

search.build do
  with(:user_ids, user.id)
  dynamic :document_read_status do
    order_by(:"unread_by_#{user.id}", :desc)
  end
end

In case you're wondering what's with the the interpolated string as the key and why I didn't use the user id as the key directly, that answer can be found here: Indexing and ordering by dynamic field with sunspot

In case there's something wrong with this approach, any input would be welcomed.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top