Tigraine
Tigraine

Reputation: 23648

Conditional order_by depending on data in Sunspot

I am wondering if there is a way to sort using some kind of if/then semantics for the sort order.

The basic requirement I am trying to adress is this:

So off the top of my head I could solve this by materializing the order field into the index by having my searchable look like this:

integer :sort_key do                                                                                                                                             
  contact_again_time.nil? ? (created_at.to_i * -1) : contact_again_time.to_i                                                                                     
end

And then do a order_by(:sort_key, :desc) to get what I want. But this way I am putting part of the sort logic inside my model and more importantly inside the Lucene Index.

Something I'd rather avoid as it feels rather wrong.

Upvotes: 3

Views: 525

Answers (1)

arun
arun

Reputation: 11013

In Solr, you can do this by adding sort parameter to your query: sort=contact_again_time desc,created_at asc

Whenever contact_again_time is present, it would sort in descending order (and use created_at to break ties, which is irrelevant to you). When only created_at is present those will be sorted in ascending order.

This should translate in a straight-forward manner to sunspot.

Update: If you want to sort like sort=contact_again_time asc,created_at asc you will get the documents where contact_again_time is missing first, like you mention in your comment below. To push these documents to the end, add sortMissingLast="true" to contact_again_time in your Solr schema.xml. If created_at can also be absent in some documents and you desire the same behavior, you should add sortMissingLast to it too.

Upvotes: 2

Related Questions