Search code examples
ruby-on-railsrubyruby-on-rails-3sunspotfaceted-search

Date range facets with Sunspot in Ruby on Rails


I am using Sunspot to search for events (parties, concerts, ...) in a Ruby on Rails 3 application.

I have managed to set up free text search and facet search on a couple of different category types.

Now, I am stuck with my next task. I want to set up facets related to when the event is occuring.

I want to have facets describing both relative date/time ranges such as "today", "this weekend", "next weekend" and absolute date/time ranges, such as "Easter Holiday 2011", "New Years Day 2012", ... The datetime ranges are sometimes overlapping each other.

I have browsed around in the Sunspot API documentation, the Sunspot wiki, here at Stackoverflow, read and loads of articles and blogs. People are writing it is possible to to achieve but I find no examples or implementation ideas that makes me understand how to do this.

Any suggestions?

Since my problem is not in my code, I don't publish any code. The class Event has a DateTime instance named "start_time". I do understand it's my job to define when the absolute date/time ranges appear in the calender.

Best regards,

./stefan

PS Did I tell I'm a newbie? ;-) DS


Solution

  • You should set up your fields as trie time fields for efficient range queries:

    class Event
      searchable do
        time :start_time, :trie => true
      end
    end
    

    Then you can use query facets to facet based on ranges:

    Event.search do
      facet :start_time do
        bod = Time.zone.now.beginning_of_day
        row :today do
          with :start_time, bod..(bod + 1)
        end
        row :tomorrow do
          with :start_time, (bod + 1)..(bod + 2)
        end
        # etc.
      end
    end
    

    The key insight here is that you can construct facets using arbitrary scopes. Note that the facet name :start_time is just used to reference the facet in the search results, and the row labels :today and :tomorrow are similarly just used on the client side to identify the row counts corresponding to those queries; they have no meaning from Solr's standpoint, so you can call them whatever you want (using whatever data type you want -- they don't have to be symbols).

    More information on query facets here: http://sunspot.github.com/docs/Sunspot/DSL/FieldQuery.html#facet-instance_method