sunspot 2.2.0 → 2.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
 - data/lib/sunspot/dsl/field_query.rb +11 -9
 - data/lib/sunspot/dsl/fulltext.rb +9 -1
 - data/lib/sunspot/dsl/group.rb +108 -0
 - data/lib/sunspot/dsl/search.rb +1 -1
 - data/lib/sunspot/dsl.rb +1 -1
 - data/lib/sunspot/field_factory.rb +28 -15
 - data/lib/sunspot/indexer.rb +63 -17
 - data/lib/sunspot/query/abstract_fulltext.rb +9 -2
 - data/lib/sunspot/query/dismax.rb +11 -4
 - data/lib/sunspot/query/{field_group.rb → group.rb} +16 -6
 - data/lib/sunspot/query/group_query.rb +17 -0
 - data/lib/sunspot/query/restriction.rb +45 -1
 - data/lib/sunspot/query.rb +1 -1
 - data/lib/sunspot/schema.rb +2 -1
 - data/lib/sunspot/search/abstract_search.rb +7 -3
 - data/lib/sunspot/search/query_group.rb +74 -0
 - data/lib/sunspot/search/standard_search.rb +1 -1
 - data/lib/sunspot/search.rb +1 -1
 - data/lib/sunspot/session.rb +16 -0
 - data/lib/sunspot/session_proxy/master_slave_session_proxy.rb +2 -2
 - data/lib/sunspot/session_proxy/retry_5xx_session_proxy.rb +1 -1
 - data/lib/sunspot/session_proxy/sharding_session_proxy.rb +4 -2
 - data/lib/sunspot/session_proxy/silent_fail_session_proxy.rb +1 -1
 - data/lib/sunspot/session_proxy/thread_local_session_proxy.rb +3 -1
 - data/lib/sunspot/type.rb +20 -0
 - data/lib/sunspot/version.rb +1 -1
 - data/lib/sunspot.rb +36 -2
 - data/spec/api/indexer/attributes_spec.rb +5 -0
 - data/spec/api/query/function_spec.rb +103 -0
 - data/spec/api/query/group_spec.rb +23 -1
 - data/spec/api/session_proxy/sharding_session_proxy_spec.rb +1 -1
 - data/spec/helpers/integration_helper.rb +9 -0
 - data/spec/integration/atomic_updates_spec.rb +44 -0
 - data/spec/integration/field_grouping_spec.rb +13 -0
 - data/spec/integration/scoped_search_spec.rb +51 -0
 - data/spec/mocks/post.rb +3 -1
 - metadata +11 -15
 - data/lib/sunspot/dsl/field_group.rb +0 -57
 
| 
         @@ -0,0 +1,74 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'sunspot/search/paginated_collection'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Sunspot
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Search
         
     | 
| 
      
 5 
     | 
    
         
            +
                class QueryGroup
         
     | 
| 
      
 6 
     | 
    
         
            +
                  def initialize(queries, search) #:nodoc:
         
     | 
| 
      
 7 
     | 
    
         
            +
                    @queries, @search = queries, search
         
     | 
| 
      
 8 
     | 
    
         
            +
                  end
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                  def groups
         
     | 
| 
      
 11 
     | 
    
         
            +
                    @groups ||=
         
     | 
| 
      
 12 
     | 
    
         
            +
                      if solr_response_for_first
         
     | 
| 
      
 13 
     | 
    
         
            +
                        groups = @queries.map { |query| Group.new(query.label, doclist_for(query), @search) }
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                        paginate_collection(groups)
         
     | 
| 
      
 16 
     | 
    
         
            +
                      end
         
     | 
| 
      
 17 
     | 
    
         
            +
                  end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                  def matches
         
     | 
| 
      
 20 
     | 
    
         
            +
                    if solr_response_for_first
         
     | 
| 
      
 21 
     | 
    
         
            +
                      solr_response_for_first['matches'].to_i
         
     | 
| 
      
 22 
     | 
    
         
            +
                    end
         
     | 
| 
      
 23 
     | 
    
         
            +
                  end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                  def total
         
     | 
| 
      
 26 
     | 
    
         
            +
                    @queries.count
         
     | 
| 
      
 27 
     | 
    
         
            +
                  end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                  #
         
     | 
| 
      
 30 
     | 
    
         
            +
                  # It populates all grouped hits at once.
         
     | 
| 
      
 31 
     | 
    
         
            +
                  # Useful for eager loading fall grouped results at once.
         
     | 
| 
      
 32 
     | 
    
         
            +
                  #
         
     | 
| 
      
 33 
     | 
    
         
            +
                  def populate_all_hits
         
     | 
| 
      
 34 
     | 
    
         
            +
                    # Init a 2 dimension Hash that contains an array per key
         
     | 
| 
      
 35 
     | 
    
         
            +
                    id_hit_hash = Hash.new { |hash, key| hash[key] = Hash.new{ |h, k| h[k] = [] } }
         
     | 
| 
      
 36 
     | 
    
         
            +
                    groups.each do |g|
         
     | 
| 
      
 37 
     | 
    
         
            +
                      # Take all hits to being populated later on
         
     | 
| 
      
 38 
     | 
    
         
            +
                      g.hits.each do |hit|
         
     | 
| 
      
 39 
     | 
    
         
            +
                        id_hit_hash[hit.class_name][hit.primary_key] |= [hit]
         
     | 
| 
      
 40 
     | 
    
         
            +
                      end
         
     | 
| 
      
 41 
     | 
    
         
            +
                    end
         
     | 
| 
      
 42 
     | 
    
         
            +
                    # Go for each class and load the results' objects into each of the hits
         
     | 
| 
      
 43 
     | 
    
         
            +
                    id_hit_hash.each_pair do |class_name, many_hits|
         
     | 
| 
      
 44 
     | 
    
         
            +
                      ids = many_hits.keys
         
     | 
| 
      
 45 
     | 
    
         
            +
                      data_accessor = @search.data_accessor_for(Util.full_const_get(class_name))
         
     | 
| 
      
 46 
     | 
    
         
            +
                      hits_for_class = id_hit_hash[class_name]
         
     | 
| 
      
 47 
     | 
    
         
            +
                      data_accessor.load_all(ids).each do |result|
         
     | 
| 
      
 48 
     | 
    
         
            +
                        hits = hits_for_class.delete(Adapters::InstanceAdapter.adapt(result).id.to_s)
         
     | 
| 
      
 49 
     | 
    
         
            +
                        hits.each{ |hit| hit.result = result }
         
     | 
| 
      
 50 
     | 
    
         
            +
                      end
         
     | 
| 
      
 51 
     | 
    
         
            +
                      hits_for_class.values.each { |hits| hits.each{|hit| hit.result = nil } }
         
     | 
| 
      
 52 
     | 
    
         
            +
                    end
         
     | 
| 
      
 53 
     | 
    
         
            +
                  end
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
                  private
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
                  def doclist_for(query)
         
     | 
| 
      
 58 
     | 
    
         
            +
                    solr_response_for(query.to_boolean_phrase)['doclist']
         
     | 
| 
      
 59 
     | 
    
         
            +
                  end
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
                  def solr_response_for(query_string)
         
     | 
| 
      
 62 
     | 
    
         
            +
                    @search.group_response[query_string]
         
     | 
| 
      
 63 
     | 
    
         
            +
                  end
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                  def solr_response_for_first
         
     | 
| 
      
 66 
     | 
    
         
            +
                    solr_response_for(@queries[0].to_boolean_phrase)
         
     | 
| 
      
 67 
     | 
    
         
            +
                  end
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
                  def paginate_collection(collection)
         
     | 
| 
      
 70 
     | 
    
         
            +
                    PaginatedCollection.new(collection, @search.query.page, @search.query.per_page, total)
         
     | 
| 
      
 71 
     | 
    
         
            +
                  end
         
     | 
| 
      
 72 
     | 
    
         
            +
                end
         
     | 
| 
      
 73 
     | 
    
         
            +
              end
         
     | 
| 
      
 74 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -70,7 +70,7 @@ module Sunspot 
     | 
|
| 
       70 
70 
     | 
    
         
             
                      # If no query was given, or all terms are present in the index,
         
     | 
| 
       71 
71 
     | 
    
         
             
                      # return Solr's suggested collation.
         
     | 
| 
       72 
72 
     | 
    
         
             
                      if terms.length == 0
         
     | 
| 
       73 
     | 
    
         
            -
                        collation = solr_spellcheck[' 
     | 
| 
      
 73 
     | 
    
         
            +
                        collation = solr_spellcheck['collations'][-1]
         
     | 
| 
       74 
74 
     | 
    
         
             
                      end
         
     | 
| 
       75 
75 
     | 
    
         | 
| 
       76 
76 
     | 
    
         
             
                      collation
         
     | 
    
        data/lib/sunspot/search.rb
    CHANGED
    
    | 
         @@ -1,6 +1,6 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            %w(abstract_search standard_search more_like_this_search query_facet field_facet
         
     | 
| 
       2 
2 
     | 
    
         
             
               date_facet range_facet facet_row hit highlight field_group group hit_enumerable
         
     | 
| 
       3 
     | 
    
         
            -
               stats_row field_stats stats_facet).each do |file|
         
     | 
| 
      
 3 
     | 
    
         
            +
               stats_row field_stats stats_facet query_group).each do |file|
         
     | 
| 
       4 
4 
     | 
    
         
             
              require File.join(File.dirname(__FILE__), 'search', file)
         
     | 
| 
       5 
5 
     | 
    
         
             
            end
         
     | 
| 
       6 
6 
     | 
    
         | 
    
        data/lib/sunspot/session.rb
    CHANGED
    
    | 
         @@ -99,6 +99,22 @@ module Sunspot 
     | 
|
| 
       99 
99 
     | 
    
         
             
                  commit
         
     | 
| 
       100 
100 
     | 
    
         
             
                end
         
     | 
| 
       101 
101 
     | 
    
         | 
| 
      
 102 
     | 
    
         
            +
                #
         
     | 
| 
      
 103 
     | 
    
         
            +
                # See Sunspot.atomic_update
         
     | 
| 
      
 104 
     | 
    
         
            +
                #
         
     | 
| 
      
 105 
     | 
    
         
            +
                def atomic_update(clazz, updates = {})
         
     | 
| 
      
 106 
     | 
    
         
            +
                  @adds += updates.keys.length
         
     | 
| 
      
 107 
     | 
    
         
            +
                  indexer.add_atomic_update(clazz, updates)
         
     | 
| 
      
 108 
     | 
    
         
            +
                end
         
     | 
| 
      
 109 
     | 
    
         
            +
             
     | 
| 
      
 110 
     | 
    
         
            +
                #
         
     | 
| 
      
 111 
     | 
    
         
            +
                # See Sunspot.atomic_update!
         
     | 
| 
      
 112 
     | 
    
         
            +
                #
         
     | 
| 
      
 113 
     | 
    
         
            +
                def atomic_update!(clazz, updates = {})
         
     | 
| 
      
 114 
     | 
    
         
            +
                  atomic_update(clazz, updates)
         
     | 
| 
      
 115 
     | 
    
         
            +
                  commit
         
     | 
| 
      
 116 
     | 
    
         
            +
                end
         
     | 
| 
      
 117 
     | 
    
         
            +
             
     | 
| 
       102 
118 
     | 
    
         
             
                #
         
     | 
| 
       103 
119 
     | 
    
         
             
                # See Sunspot.commit
         
     | 
| 
       104 
120 
     | 
    
         
             
                #
         
     | 
| 
         @@ -19,8 +19,8 @@ module Sunspot 
     | 
|
| 
       19 
19 
     | 
    
         | 
| 
       20 
20 
     | 
    
         
             
                  delegate :batch, :commit, :commit_if_delete_dirty, :commit_if_dirty,
         
     | 
| 
       21 
21 
     | 
    
         
             
                           :config, :delete_dirty?, :dirty?, :index, :index!, :optimize, :remove,
         
     | 
| 
       22 
     | 
    
         
            -
                           :remove!, :remove_all, :remove_all!, :remove_by_id,
         
     | 
| 
       23 
     | 
    
         
            -
                           : 
     | 
| 
      
 22 
     | 
    
         
            +
                           :remove!, :remove_all, :remove_all!, :remove_by_id, :remove_by_id!,
         
     | 
| 
      
 23 
     | 
    
         
            +
                           :atomic_update, :atomic_update!, :to => :master_session
         
     | 
| 
       24 
24 
     | 
    
         
             
                  delegate :new_search, :search, :new_more_like_this, :more_like_this, :to => :slave_session
         
     | 
| 
       25 
25 
     | 
    
         | 
| 
       26 
26 
     | 
    
         
             
                  def initialize(master_session, slave_session)
         
     | 
| 
         @@ -59,7 +59,7 @@ module Sunspot 
     | 
|
| 
       59 
59 
     | 
    
         | 
| 
       60 
60 
     | 
    
         
             
                  delegate :batch, :commit, :commit_if_dirty, :commit_if_delete_dirty,
         
     | 
| 
       61 
61 
     | 
    
         
             
                    :dirty?, :index!, :index, :optimize, :remove!, :remove, :remove_all!,
         
     | 
| 
       62 
     | 
    
         
            -
                    :remove_all, :remove_by_id!, :remove_by_id,
         
     | 
| 
      
 62 
     | 
    
         
            +
                    :remove_all, :remove_by_id!, :remove_by_id, :atomic_update, :atomic_update!,
         
     | 
| 
       63 
63 
     | 
    
         
             
                    :to => :retry_handler
         
     | 
| 
       64 
64 
     | 
    
         | 
| 
       65 
65 
     | 
    
         
             
                end
         
     | 
| 
         @@ -27,9 +27,11 @@ module Sunspot 
     | 
|
| 
       27 
27 
     | 
    
         
             
                # * remove_by_id!
         
     | 
| 
       28 
28 
     | 
    
         
             
                # * remove_all with an argument
         
     | 
| 
       29 
29 
     | 
    
         
             
                # * remove_all! with an argument
         
     | 
| 
      
 30 
     | 
    
         
            +
                # * atomic_update with arguments
         
     | 
| 
      
 31 
     | 
    
         
            +
                # * atomic_update! with arguments
         
     | 
| 
       30 
32 
     | 
    
         
             
                #
         
     | 
| 
       31 
33 
     | 
    
         
             
                class ShardingSessionProxy < AbstractSessionProxy
         
     | 
| 
       32 
     | 
    
         
            -
                  not_supported :batch, :config, :remove_by_id, :remove_by_id!
         
     | 
| 
      
 34 
     | 
    
         
            +
                  not_supported :batch, :config, :remove_by_id, :remove_by_id!, :atomic_update, :atomic_update!
         
     | 
| 
       33 
35 
     | 
    
         | 
| 
       34 
36 
     | 
    
         
             
                  # 
         
     | 
| 
       35 
37 
     | 
    
         
             
                  # +search_session+ is the session that should be used for searching.
         
     | 
| 
         @@ -70,7 +72,7 @@ module Sunspot 
     | 
|
| 
       70 
72 
     | 
    
         
             
                    using_sharded_session(objects) { |session, group| session.index!(group) }
         
     | 
| 
       71 
73 
     | 
    
         
             
                  end
         
     | 
| 
       72 
74 
     | 
    
         | 
| 
       73 
     | 
    
         
            -
                  # 
     | 
| 
      
 75 
     | 
    
         
            +
                  #
         
     | 
| 
       74 
76 
     | 
    
         
             
                  # See Sunspot.remove
         
     | 
| 
       75 
77 
     | 
    
         
             
                  #
         
     | 
| 
       76 
78 
     | 
    
         
             
                  def remove(*objects)
         
     | 
| 
         @@ -22,7 +22,7 @@ module Sunspot 
     | 
|
| 
       22 
22 
     | 
    
         
             
                  SUPPORTED_METHODS = [
         
     | 
| 
       23 
23 
     | 
    
         
             
                    :batch, :commit, :commit_if_dirty, :commit_if_delete_dirty, :dirty?,
         
     | 
| 
       24 
24 
     | 
    
         
             
                    :index!, :index, :optimize, :remove!, :remove, :remove_all!, :remove_all,
         
     | 
| 
       25 
     | 
    
         
            -
                    :remove_by_id!, :remove_by_id
         
     | 
| 
      
 25 
     | 
    
         
            +
                    :remove_by_id!, :remove_by_id, :atomic_update, :atomic_update!
         
     | 
| 
       26 
26 
     | 
    
         
             
                  ]
         
     | 
| 
       27 
27 
     | 
    
         | 
| 
       28 
28 
     | 
    
         
             
                  SUPPORTED_METHODS.each do |method|
         
     | 
| 
         @@ -17,7 +17,9 @@ module Sunspot 
     | 
|
| 
       17 
17 
     | 
    
         
             
                  attr_reader :config
         
     | 
| 
       18 
18 
     | 
    
         
             
                  @@next_id = 0
         
     | 
| 
       19 
19 
     | 
    
         | 
| 
       20 
     | 
    
         
            -
                  delegate :batch, :commit, :commit_if_delete_dirty, :commit_if_dirty, :delete_dirty?, :dirty?, :index, :index!, 
     | 
| 
      
 20 
     | 
    
         
            +
                  delegate :batch, :commit, :commit_if_delete_dirty, :commit_if_dirty, :delete_dirty?, :dirty?, :index, :index!,
         
     | 
| 
      
 21 
     | 
    
         
            +
                           :new_search, :optimize, :remove, :remove!, :remove_all, :remove_all!, :remove_by_id, :remove_by_id!,
         
     | 
| 
      
 22 
     | 
    
         
            +
                           :search, :more_like_this, :new_more_like_this, :atomic_update, :atomic_update!, :to => :session
         
     | 
| 
       21 
23 
     | 
    
         | 
| 
       22 
24 
     | 
    
         
             
                  # 
         
     | 
| 
       23 
25 
     | 
    
         
             
                  # Optionally pass an existing Sunspot::Configuration object. If none is
         
     | 
    
        data/lib/sunspot/type.rb
    CHANGED
    
    | 
         @@ -375,6 +375,26 @@ module Sunspot 
     | 
|
| 
       375 
375 
     | 
    
         
             
                  end
         
     | 
| 
       376 
376 
     | 
    
         
             
                end
         
     | 
| 
       377 
377 
     | 
    
         | 
| 
      
 378 
     | 
    
         
            +
                class DateRangeType < DateType
         
     | 
| 
      
 379 
     | 
    
         
            +
                  def indexed_name(name)
         
     | 
| 
      
 380 
     | 
    
         
            +
                    "#{name}_dr"
         
     | 
| 
      
 381 
     | 
    
         
            +
                  end
         
     | 
| 
      
 382 
     | 
    
         
            +
             
     | 
| 
      
 383 
     | 
    
         
            +
                  def to_indexed(value)
         
     | 
| 
      
 384 
     | 
    
         
            +
                    if value.respond_to?(:first) && value.respond_to?(:last)
         
     | 
| 
      
 385 
     | 
    
         
            +
                      "[#{super value.first} TO #{super value.last}]"
         
     | 
| 
      
 386 
     | 
    
         
            +
                    else
         
     | 
| 
      
 387 
     | 
    
         
            +
                      super value
         
     | 
| 
      
 388 
     | 
    
         
            +
                    end
         
     | 
| 
      
 389 
     | 
    
         
            +
                  end
         
     | 
| 
      
 390 
     | 
    
         
            +
             
     | 
| 
      
 391 
     | 
    
         
            +
                  def cast(value)
         
     | 
| 
      
 392 
     | 
    
         
            +
                    return super unless m = value.match(/^\[(?<start>.+) TO (?<end>.+)\]$/)
         
     | 
| 
      
 393 
     | 
    
         
            +
                    Range.new super(m[:start]), super(m[:end])
         
     | 
| 
      
 394 
     | 
    
         
            +
                  end
         
     | 
| 
      
 395 
     | 
    
         
            +
                end
         
     | 
| 
      
 396 
     | 
    
         
            +
                register DateRangeType, Range
         
     | 
| 
      
 397 
     | 
    
         
            +
             
     | 
| 
       378 
398 
     | 
    
         
             
                class ClassType < AbstractType
         
     | 
| 
       379 
399 
     | 
    
         
             
                  def indexed_name(name) #:nodoc:
         
     | 
| 
       380 
400 
     | 
    
         
             
                    'class_name'
         
     | 
    
        data/lib/sunspot/version.rb
    CHANGED
    
    
    
        data/lib/sunspot.rb
    CHANGED
    
    | 
         @@ -196,6 +196,40 @@ module Sunspot 
     | 
|
| 
       196 
196 
     | 
    
         
             
                  session.index!(*objects)
         
     | 
| 
       197 
197 
     | 
    
         
             
                end
         
     | 
| 
       198 
198 
     | 
    
         | 
| 
      
 199 
     | 
    
         
            +
                # Atomic update object properties on the singleton session.
         
     | 
| 
      
 200 
     | 
    
         
            +
                #
         
     | 
| 
      
 201 
     | 
    
         
            +
                # ==== Parameters
         
     | 
| 
      
 202 
     | 
    
         
            +
                #
         
     | 
| 
      
 203 
     | 
    
         
            +
                # clazz<Class>:: the class of the objects to be updated
         
     | 
| 
      
 204 
     | 
    
         
            +
                # updates<Hash>:: hash of updates where keys are model ids
         
     | 
| 
      
 205 
     | 
    
         
            +
                #                 and values are hash with property name/values to be updated
         
     | 
| 
      
 206 
     | 
    
         
            +
                #
         
     | 
| 
      
 207 
     | 
    
         
            +
                # ==== Example
         
     | 
| 
      
 208 
     | 
    
         
            +
                #
         
     | 
| 
      
 209 
     | 
    
         
            +
                #   post1, post2 = new Array(2) { Post.create }
         
     | 
| 
      
 210 
     | 
    
         
            +
                #   Sunspot.atomic_update(Post, post1.id => {title: 'New Title'}, post2.id => {description: 'new description'})
         
     | 
| 
      
 211 
     | 
    
         
            +
                #
         
     | 
| 
      
 212 
     | 
    
         
            +
                # Note that indexed objects won't be reflected in search until a commit is
         
     | 
| 
      
 213 
     | 
    
         
            +
                # sent - see Sunspot.index! and Sunspot.commit
         
     | 
| 
      
 214 
     | 
    
         
            +
                #
         
     | 
| 
      
 215 
     | 
    
         
            +
                def atomic_update(clazz, updates = {})
         
     | 
| 
      
 216 
     | 
    
         
            +
                  session.atomic_update(clazz, updates)
         
     | 
| 
      
 217 
     | 
    
         
            +
                end
         
     | 
| 
      
 218 
     | 
    
         
            +
             
     | 
| 
      
 219 
     | 
    
         
            +
                # Atomic update object properties on the singleton session.
         
     | 
| 
      
 220 
     | 
    
         
            +
                #
         
     | 
| 
      
 221 
     | 
    
         
            +
                # See: Sunspot.atomic_update and Sunspot.commit
         
     | 
| 
      
 222 
     | 
    
         
            +
                #
         
     | 
| 
      
 223 
     | 
    
         
            +
                # ==== Parameters
         
     | 
| 
      
 224 
     | 
    
         
            +
                #
         
     | 
| 
      
 225 
     | 
    
         
            +
                # clazz<Class>:: the class of the objects to be updated
         
     | 
| 
      
 226 
     | 
    
         
            +
                # updates<Hash>:: hash of updates where keys are model ids
         
     | 
| 
      
 227 
     | 
    
         
            +
                #                 and values are hash with property name/values to be updated
         
     | 
| 
      
 228 
     | 
    
         
            +
                #
         
     | 
| 
      
 229 
     | 
    
         
            +
                def atomic_update!(clazz, updates = {})
         
     | 
| 
      
 230 
     | 
    
         
            +
                  session.atomic_update!(clazz, updates)
         
     | 
| 
      
 231 
     | 
    
         
            +
                end
         
     | 
| 
      
 232 
     | 
    
         
            +
             
     | 
| 
       199 
233 
     | 
    
         
             
                # Commits (soft or hard) the singleton session
         
     | 
| 
       200 
234 
     | 
    
         
             
                #
         
     | 
| 
       201 
235 
     | 
    
         
             
                # When documents are added to or removed from Solr, the changes are
         
     | 
| 
         @@ -490,9 +524,9 @@ module Sunspot 
     | 
|
| 
       490 
524 
     | 
    
         
             
                #
         
     | 
| 
       491 
525 
     | 
    
         
             
                #   Sunspot.batch do
         
     | 
| 
       492 
526 
     | 
    
         
             
                #     post = Post.new
         
     | 
| 
       493 
     | 
    
         
            -
                #     Sunspot. 
     | 
| 
      
 527 
     | 
    
         
            +
                #     Sunspot.index(post)
         
     | 
| 
       494 
528 
     | 
    
         
             
                #     comment = Comment.new
         
     | 
| 
       495 
     | 
    
         
            -
                #     Sunspot. 
     | 
| 
      
 529 
     | 
    
         
            +
                #     Sunspot.index(comment)
         
     | 
| 
       496 
530 
     | 
    
         
             
                #   end
         
     | 
| 
       497 
531 
     | 
    
         
             
                #
         
     | 
| 
       498 
532 
     | 
    
         
             
                # Sunspot will send both the post and the comment in a single request.
         
     | 
| 
         @@ -71,6 +71,11 @@ describe 'indexing attribute fields', :type => :indexer do 
     | 
|
| 
       71 
71 
     | 
    
         
             
                connection.should have_add_with(:expire_date_d => '2009-07-13T00:00:00Z')
         
     | 
| 
       72 
72 
     | 
    
         
             
              end
         
     | 
| 
       73 
73 
     | 
    
         | 
| 
      
 74 
     | 
    
         
            +
              it 'should correctly index a date range field' do
         
     | 
| 
      
 75 
     | 
    
         
            +
                session.index(post(:featured_for => Date.new(2009, 07, 13)..Date.new(2009, 12, 25)))
         
     | 
| 
      
 76 
     | 
    
         
            +
                connection.should have_add_with(:featured_for_dr => '[2009-07-13T00:00:00Z TO 2009-12-25T00:00:00Z]')
         
     | 
| 
      
 77 
     | 
    
         
            +
              end
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
       74 
79 
     | 
    
         
             
              it 'should correctly index a boolean field' do
         
     | 
| 
       75 
80 
     | 
    
         
             
                session.index(post(:featured => true))
         
     | 
| 
       76 
81 
     | 
    
         
             
                connection.should have_add_with(:featured_bs => 'true')
         
     | 
| 
         @@ -102,5 +102,108 @@ describe 'function query' do 
     | 
|
| 
       102 
102 
     | 
    
         
             
                  end
         
     | 
| 
       103 
103 
     | 
    
         
             
                end.should raise_error(Sunspot::UnrecognizedFieldError)
         
     | 
| 
       104 
104 
     | 
    
         
             
              end
         
     | 
| 
      
 105 
     | 
    
         
            +
             
     | 
| 
      
 106 
     | 
    
         
            +
              it "should send query to solr with multiplicative boost function" do
         
     | 
| 
      
 107 
     | 
    
         
            +
                session.search Post do
         
     | 
| 
      
 108 
     | 
    
         
            +
                  keywords('pizza') do
         
     | 
| 
      
 109 
     | 
    
         
            +
                    multiplicative_boost(function { :average_rating })
         
     | 
| 
      
 110 
     | 
    
         
            +
                  end
         
     | 
| 
      
 111 
     | 
    
         
            +
                end
         
     | 
| 
      
 112 
     | 
    
         
            +
                connection.should have_last_search_including(:boost, 'average_rating_ft')
         
     | 
| 
      
 113 
     | 
    
         
            +
              end
         
     | 
| 
      
 114 
     | 
    
         
            +
             
     | 
| 
      
 115 
     | 
    
         
            +
              it "should send query to solr with multiplicative boost function and boost amount" do
         
     | 
| 
      
 116 
     | 
    
         
            +
                session.search Post do
         
     | 
| 
      
 117 
     | 
    
         
            +
                  keywords('pizza') do
         
     | 
| 
      
 118 
     | 
    
         
            +
                    multiplicative_boost(function { :average_rating }^5)
         
     | 
| 
      
 119 
     | 
    
         
            +
                  end
         
     | 
| 
      
 120 
     | 
    
         
            +
                end
         
     | 
| 
      
 121 
     | 
    
         
            +
                connection.should have_last_search_including(:boost, 'average_rating_ft^5')
         
     | 
| 
      
 122 
     | 
    
         
            +
              end
         
     | 
| 
      
 123 
     | 
    
         
            +
             
     | 
| 
      
 124 
     | 
    
         
            +
              it "should handle multiplicative boost function with constant float" do
         
     | 
| 
      
 125 
     | 
    
         
            +
                session.search Post do
         
     | 
| 
      
 126 
     | 
    
         
            +
                  keywords('pizza') do
         
     | 
| 
      
 127 
     | 
    
         
            +
                    multiplicative_boost(function { 10.5 })
         
     | 
| 
      
 128 
     | 
    
         
            +
                  end
         
     | 
| 
      
 129 
     | 
    
         
            +
                end
         
     | 
| 
      
 130 
     | 
    
         
            +
                connection.should have_last_search_including(:boost, '10.5')
         
     | 
| 
      
 131 
     | 
    
         
            +
              end
         
     | 
| 
      
 132 
     | 
    
         
            +
             
     | 
| 
      
 133 
     | 
    
         
            +
              it "should handle multiplicative boost function with constant float and boost amount" do
         
     | 
| 
      
 134 
     | 
    
         
            +
                session.search Post do
         
     | 
| 
      
 135 
     | 
    
         
            +
                  keywords('pizza') do
         
     | 
| 
      
 136 
     | 
    
         
            +
                    multiplicative_boost(function { 10.5 }^5)
         
     | 
| 
      
 137 
     | 
    
         
            +
                  end
         
     | 
| 
      
 138 
     | 
    
         
            +
                end
         
     | 
| 
      
 139 
     | 
    
         
            +
                connection.should have_last_search_including(:boost, '10.5^5')
         
     | 
| 
      
 140 
     | 
    
         
            +
              end
         
     | 
| 
      
 141 
     | 
    
         
            +
             
     | 
| 
      
 142 
     | 
    
         
            +
              it "should handle multiplicative boost function with time literal" do
         
     | 
| 
      
 143 
     | 
    
         
            +
                session.search Post do
         
     | 
| 
      
 144 
     | 
    
         
            +
                  keywords('pizza') do
         
     | 
| 
      
 145 
     | 
    
         
            +
                    multiplicative_boost(function { Time.parse('2010-03-25 14:13:00 EDT') })
         
     | 
| 
      
 146 
     | 
    
         
            +
                  end
         
     | 
| 
      
 147 
     | 
    
         
            +
                end
         
     | 
| 
      
 148 
     | 
    
         
            +
                connection.should have_last_search_including(:boost, '2010-03-25T18:13:00Z')
         
     | 
| 
      
 149 
     | 
    
         
            +
              end
         
     | 
| 
      
 150 
     | 
    
         
            +
             
         
     | 
| 
      
 151 
     | 
    
         
            +
              it "should handle arbitrary functions in a function query block" do
         
     | 
| 
      
 152 
     | 
    
         
            +
                session.search Post do
         
     | 
| 
      
 153 
     | 
    
         
            +
                  keywords('pizza') do
         
     | 
| 
      
 154 
     | 
    
         
            +
                    multiplicative_boost(function { product(:average_rating, 10) })
         
     | 
| 
      
 155 
     | 
    
         
            +
                  end
         
     | 
| 
      
 156 
     | 
    
         
            +
                end
         
     | 
| 
      
 157 
     | 
    
         
            +
                connection.should have_last_search_including(:boost, 'product(average_rating_ft,10)')
         
     | 
| 
      
 158 
     | 
    
         
            +
              end
         
     | 
| 
      
 159 
     | 
    
         
            +
             
     | 
| 
      
 160 
     | 
    
         
            +
              it "should handle the sub function in a multiplicative boost function query block" do
         
     | 
| 
      
 161 
     | 
    
         
            +
                session.search Post do
         
     | 
| 
      
 162 
     | 
    
         
            +
                  keywords('pizza') do
         
     | 
| 
      
 163 
     | 
    
         
            +
                    multiplicative_boost(function { sub(:average_rating, 10) })
         
     | 
| 
      
 164 
     | 
    
         
            +
                  end
         
     | 
| 
      
 165 
     | 
    
         
            +
                end
         
     | 
| 
      
 166 
     | 
    
         
            +
                connection.should have_last_search_including(:boost, 'sub(average_rating_ft,10)')
         
     | 
| 
      
 167 
     | 
    
         
            +
              end
         
     | 
| 
      
 168 
     | 
    
         
            +
             
     | 
| 
      
 169 
     | 
    
         
            +
              it "should handle boost amounts on multiplicative boost function query block" do
         
     | 
| 
      
 170 
     | 
    
         
            +
                session.search Post do
         
     | 
| 
      
 171 
     | 
    
         
            +
                  keywords('pizza') do
         
     | 
| 
      
 172 
     | 
    
         
            +
                    multiplicative_boost(function { sub(:average_rating, 10)^5 })
         
     | 
| 
      
 173 
     | 
    
         
            +
                  end
         
     | 
| 
      
 174 
     | 
    
         
            +
                end
         
     | 
| 
      
 175 
     | 
    
         
            +
                connection.should have_last_search_including(:boost, 'sub(average_rating_ft,10)^5')
         
     | 
| 
      
 176 
     | 
    
         
            +
              end
         
     | 
| 
      
 177 
     | 
    
         
            +
             
         
     | 
| 
      
 178 
     | 
    
         
            +
              it "should handle nested functions in a multiplicative boost function query block" do
         
     | 
| 
      
 179 
     | 
    
         
            +
                session.search Post do
         
     | 
| 
      
 180 
     | 
    
         
            +
                  keywords('pizza') do
         
     | 
| 
      
 181 
     | 
    
         
            +
                    multiplicative_boost(function { product(:average_rating, sum(:average_rating, 20)) })
         
     | 
| 
      
 182 
     | 
    
         
            +
                  end
         
     | 
| 
      
 183 
     | 
    
         
            +
                end
         
     | 
| 
      
 184 
     | 
    
         
            +
                connection.should have_last_search_including(:boost, 'product(average_rating_ft,sum(average_rating_ft,20))')
         
     | 
| 
      
 185 
     | 
    
         
            +
              end
         
     | 
| 
      
 186 
     | 
    
         
            +
             
     | 
| 
      
 187 
     | 
    
         
            +
              # TODO SOLR 1.5
         
     | 
| 
      
 188 
     | 
    
         
            +
              it "should raise ArgumentError if string literal passed to multiplicative boost" do
         
     | 
| 
      
 189 
     | 
    
         
            +
                lambda do
         
     | 
| 
      
 190 
     | 
    
         
            +
                  session.search Post do
         
     | 
| 
      
 191 
     | 
    
         
            +
                    keywords('pizza') do
         
     | 
| 
      
 192 
     | 
    
         
            +
                      multiplicative_boost(function { "hello world" })
         
     | 
| 
      
 193 
     | 
    
         
            +
                    end
         
     | 
| 
      
 194 
     | 
    
         
            +
                  end
         
     | 
| 
      
 195 
     | 
    
         
            +
                end.should raise_error(ArgumentError)
         
     | 
| 
      
 196 
     | 
    
         
            +
              end
         
     | 
| 
      
 197 
     | 
    
         
            +
             
     | 
| 
      
 198 
     | 
    
         
            +
              it "should raise UnrecognizedFieldError if bogus field name passed to multiplicative boost" do
         
     | 
| 
      
 199 
     | 
    
         
            +
                lambda do
         
     | 
| 
      
 200 
     | 
    
         
            +
                  session.search Post do
         
     | 
| 
      
 201 
     | 
    
         
            +
                    keywords('pizza') do
         
     | 
| 
      
 202 
     | 
    
         
            +
                      multiplicative_boost(function { :bogus })
         
     | 
| 
      
 203 
     | 
    
         
            +
                    end
         
     | 
| 
      
 204 
     | 
    
         
            +
                  end
         
     | 
| 
      
 205 
     | 
    
         
            +
                end.should raise_error(Sunspot::UnrecognizedFieldError)
         
     | 
| 
      
 206 
     | 
    
         
            +
              end
         
     | 
| 
      
 207 
     | 
    
         
            +
             
     | 
| 
       105 
208 
     | 
    
         
             
            end
         
     | 
| 
       106 
209 
     | 
    
         | 
| 
         @@ -1,6 +1,6 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            require File.expand_path('spec_helper', File.dirname(__FILE__))
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
     | 
    
         
            -
            describe " 
     | 
| 
      
 3 
     | 
    
         
            +
            describe "grouping" do
         
     | 
| 
       4 
4 
     | 
    
         
             
              it "sends grouping parameters to solr" do
         
     | 
| 
       5 
5 
     | 
    
         
             
                session.search Post do
         
     | 
| 
       6 
6 
     | 
    
         
             
                  group :title
         
     | 
| 
         @@ -29,4 +29,26 @@ describe "field grouping" do 
     | 
|
| 
       29 
29 
     | 
    
         | 
| 
       30 
30 
     | 
    
         
             
                connection.should have_last_search_including(:"group.sort", "average_rating_ft asc")
         
     | 
| 
       31 
31 
     | 
    
         
             
              end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
              it "sends grouping field parameters to solr" do
         
     | 
| 
      
 34 
     | 
    
         
            +
                session.search Post do
         
     | 
| 
      
 35 
     | 
    
         
            +
                  group do
         
     | 
| 
      
 36 
     | 
    
         
            +
                    field :title
         
     | 
| 
      
 37 
     | 
    
         
            +
                  end
         
     | 
| 
      
 38 
     | 
    
         
            +
                end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                connection.should have_last_search_including(:"group.field", "title_ss")
         
     | 
| 
      
 41 
     | 
    
         
            +
              end
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
              it "sends grouping query parameters to solr" do
         
     | 
| 
      
 44 
     | 
    
         
            +
                session.search Post do
         
     | 
| 
      
 45 
     | 
    
         
            +
                  group do
         
     | 
| 
      
 46 
     | 
    
         
            +
                    query 'category 1' do
         
     | 
| 
      
 47 
     | 
    
         
            +
                      with(:category_ids, 1)
         
     | 
| 
      
 48 
     | 
    
         
            +
                    end
         
     | 
| 
      
 49 
     | 
    
         
            +
                  end
         
     | 
| 
      
 50 
     | 
    
         
            +
                end
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
                connection.should have_last_search_including(:"group.query", "category_ids_im:1")
         
     | 
| 
      
 53 
     | 
    
         
            +
              end
         
     | 
| 
       32 
54 
     | 
    
         
             
            end
         
     | 
| 
         @@ -15,7 +15,7 @@ describe Sunspot::SessionProxy::ShardingSessionProxy do 
     | 
|
| 
       15 
15 
     | 
    
         
             
                end
         
     | 
| 
       16 
16 
     | 
    
         
             
              end
         
     | 
| 
       17 
17 
     | 
    
         | 
| 
       18 
     | 
    
         
            -
              [:remove_by_id, :remove_by_id!].each do |method|
         
     | 
| 
      
 18 
     | 
    
         
            +
              [:remove_by_id, :remove_by_id!, :atomic_update, :atomic_update!].each do |method|
         
     | 
| 
       19 
19 
     | 
    
         
             
                it "should raise NotSupportedError when #{method} called" do
         
     | 
| 
       20 
20 
     | 
    
         
             
                  lambda { @proxy.send(method, Post, 1) }.should raise_error(Sunspot::SessionProxy::NotSupportedError)
         
     | 
| 
       21 
21 
     | 
    
         
             
                end
         
     | 
| 
         @@ -5,4 +5,13 @@ module IntegrationHelper 
     | 
|
| 
       5 
5 
     | 
    
         
             
                  Sunspot.reset!(true)
         
     | 
| 
       6 
6 
     | 
    
         
             
                end
         
     | 
| 
       7 
7 
     | 
    
         
             
              end
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
              def featured_for_posts(method, param, negated = false)
         
     | 
| 
      
 10 
     | 
    
         
            +
                with_method = negated ? :without : :with
         
     | 
| 
      
 11 
     | 
    
         
            +
                param = date_ranges[param] if param.is_a? String
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                Sunspot.search(Post) do
         
     | 
| 
      
 14 
     | 
    
         
            +
                  send(with_method, :featured_for).send(method, param)
         
     | 
| 
      
 15 
     | 
    
         
            +
                end.results
         
     | 
| 
      
 16 
     | 
    
         
            +
              end
         
     | 
| 
       8 
17 
     | 
    
         
             
            end
         
     | 
| 
         @@ -0,0 +1,44 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require File.expand_path('../spec_helper', File.dirname(__FILE__))
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            describe 'atomic updates' do
         
     | 
| 
      
 4 
     | 
    
         
            +
              before :all do
         
     | 
| 
      
 5 
     | 
    
         
            +
                Sunspot.remove_all
         
     | 
| 
      
 6 
     | 
    
         
            +
              end
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
              def validate_hit(hit, title, featured)
         
     | 
| 
      
 9 
     | 
    
         
            +
                hit.stored(:title).should == title
         
     | 
| 
      
 10 
     | 
    
         
            +
                hit.stored(:featured).should == featured
         
     | 
| 
      
 11 
     | 
    
         
            +
              end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
              def find_indexed_post(id)
         
     | 
| 
      
 14 
     | 
    
         
            +
                hit = Sunspot.search(Post).hits.find{ |h| h.primary_key.to_i == id }
         
     | 
| 
      
 15 
     | 
    
         
            +
                hit.should_not be_nil
         
     | 
| 
      
 16 
     | 
    
         
            +
                hit
         
     | 
| 
      
 17 
     | 
    
         
            +
              end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
              it 'should update single record fields one by one' do
         
     | 
| 
      
 20 
     | 
    
         
            +
                post = Post.new(title: 'A Title', featured: true)
         
     | 
| 
      
 21 
     | 
    
         
            +
                Sunspot.index!(post)
         
     | 
| 
      
 22 
     | 
    
         
            +
                
         
     | 
| 
      
 23 
     | 
    
         
            +
                validate_hit(find_indexed_post(post.id), post.title, post.featured)
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                Sunspot.atomic_update!(Post, post.id => {title: 'A New Title'})
         
     | 
| 
      
 26 
     | 
    
         
            +
                validate_hit(find_indexed_post(post.id), 'A New Title', true)
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                Sunspot.atomic_update!(Post, post.id => {featured: false})
         
     | 
| 
      
 29 
     | 
    
         
            +
                validate_hit(find_indexed_post(post.id), 'A New Title', false)
         
     | 
| 
      
 30 
     | 
    
         
            +
              end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
              it 'should update fields for multiple records' do
         
     | 
| 
      
 33 
     | 
    
         
            +
                post1 = Post.new(title: 'A First Title', featured: true)
         
     | 
| 
      
 34 
     | 
    
         
            +
                post2 = Post.new(title: 'A Second Title', featured: false)
         
     | 
| 
      
 35 
     | 
    
         
            +
                Sunspot.index!(post1, post2)
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                validate_hit(find_indexed_post(post1.id), post1.title, post1.featured)
         
     | 
| 
      
 38 
     | 
    
         
            +
                validate_hit(find_indexed_post(post2.id), post2.title, post2.featured)
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                Sunspot.atomic_update!(Post, post1.id => {title: 'A New Title'}, post2.id => {featured: true})
         
     | 
| 
      
 41 
     | 
    
         
            +
                validate_hit(find_indexed_post(post1.id), 'A New Title', true)
         
     | 
| 
      
 42 
     | 
    
         
            +
                validate_hit(find_indexed_post(post2.id), 'A Second Title', true)
         
     | 
| 
      
 43 
     | 
    
         
            +
              end
         
     | 
| 
      
 44 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -72,6 +72,19 @@ describe "field grouping" do 
     | 
|
| 
       72 
72 
     | 
    
         
             
                title1_group.hits.first.primary_key.to_i.should == highest_ranked_post.id
         
     | 
| 
       73 
73 
     | 
    
         
             
              end
         
     | 
| 
       74 
74 
     | 
    
         | 
| 
      
 75 
     | 
    
         
            +
              it "allows specification of an ordering function within groups" do
         
     | 
| 
      
 76 
     | 
    
         
            +
                search = Sunspot.search(Post) do
         
     | 
| 
      
 77 
     | 
    
         
            +
                  group :title do
         
     | 
| 
      
 78 
     | 
    
         
            +
                    order_by_function(:product, :average_rating, -2, :asc)
         
     | 
| 
      
 79 
     | 
    
         
            +
                  end
         
     | 
| 
      
 80 
     | 
    
         
            +
                end
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
      
 82 
     | 
    
         
            +
                highest_ranked_post = @posts.sort_by { |p| -p.ratings_average }.first
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
                title1_group = search.group(:title).groups.detect { |g| g.value == "Title1" }
         
     | 
| 
      
 85 
     | 
    
         
            +
                title1_group.hits.first.primary_key.to_i.should == highest_ranked_post.id
         
     | 
| 
      
 86 
     | 
    
         
            +
              end
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
       75 
88 
     | 
    
         
             
              it "allows pagination within groups" do
         
     | 
| 
       76 
89 
     | 
    
         
             
                search = Sunspot.search(Post) do
         
     | 
| 
       77 
90 
     | 
    
         
             
                  group :title
         
     | 
| 
         @@ -127,6 +127,57 @@ describe 'scoped_search' do 
     | 
|
| 
       127 
127 
     | 
    
         
             
              test_field_type 'Trie Time', :created_at, :created_at, Photo, *(['1970-01-01 00:00:00 UTC', '1983-07-08 04:00:00 UTC', '1983-07-08 02:00:00 -0500',
         
     | 
| 
       128 
128 
     | 
    
         
             
                                                                               '2005-11-05 10:00:00 UTC', Time.now.to_s].map { |t| Time.parse(t) })
         
     | 
| 
       129 
129 
     | 
    
         | 
| 
      
 130 
     | 
    
         
            +
              describe 'Date range field type' do
         
     | 
| 
      
 131 
     | 
    
         
            +
                let(:january) { Date.new(2015,1,1)..Date.new(2015,1,31) }
         
     | 
| 
      
 132 
     | 
    
         
            +
                let(:february) { Date.new(2015,2,1)..Date.new(2015,2,28) }
         
     | 
| 
      
 133 
     | 
    
         
            +
                let(:date_ranges) do
         
     | 
| 
      
 134 
     | 
    
         
            +
                  {
         
     | 
| 
      
 135 
     | 
    
         
            +
                    'December and January' => Date.new(2014,12,25)..Date.new(2015,1,10),
         
     | 
| 
      
 136 
     | 
    
         
            +
                    'January only' => Date.new(2015,1,5)..Date.new(2015,1,20),
         
     | 
| 
      
 137 
     | 
    
         
            +
                    'January and February' => Date.new(2015,1,25)..Date.new(2015,2,10),
         
     | 
| 
      
 138 
     | 
    
         
            +
                    'February only' => Date.new(2015,2,5)..Date.new(2015,2,20),
         
     | 
| 
      
 139 
     | 
    
         
            +
                    'December to February' => Date.new(2014,12,25)..Date.new(2015,2,10),
         
     | 
| 
      
 140 
     | 
    
         
            +
                    'January to March' => Date.new(2015,1,25)..Date.new(2015,3,10),
         
     | 
| 
      
 141 
     | 
    
         
            +
                    'December to March' => Date.new(2014,12,25)..Date.new(2015,3,20)
         
     | 
| 
      
 142 
     | 
    
         
            +
                  }
         
     | 
| 
      
 143 
     | 
    
         
            +
                end
         
     | 
| 
      
 144 
     | 
    
         
            +
             
     | 
| 
      
 145 
     | 
    
         
            +
                before :all do
         
     | 
| 
      
 146 
     | 
    
         
            +
                  Sunspot.remove_all
         
     | 
| 
      
 147 
     | 
    
         
            +
                  @posts = [Post.new(featured_for: january), Post.new(featured_for: february), Post.new]
         
     | 
| 
      
 148 
     | 
    
         
            +
                  Sunspot.index!(@posts)
         
     | 
| 
      
 149 
     | 
    
         
            +
                end
         
     | 
| 
      
 150 
     | 
    
         
            +
             
     | 
| 
      
 151 
     | 
    
         
            +
                it 'should filter by Contains' do
         
     | 
| 
      
 152 
     | 
    
         
            +
                  featured_for_posts(:containing, Date.new(2015,1,15) ).should == [@posts[0]]
         
     | 
| 
      
 153 
     | 
    
         
            +
                  featured_for_posts(:containing, 'December and January').should be_empty
         
     | 
| 
      
 154 
     | 
    
         
            +
                  featured_for_posts(:containing, 'January only').should == [@posts[0]]
         
     | 
| 
      
 155 
     | 
    
         
            +
                  featured_for_posts(:containing, 'January only', negated = true).should == @posts[1..-1]
         
     | 
| 
      
 156 
     | 
    
         
            +
                end
         
     | 
| 
      
 157 
     | 
    
         
            +
             
     | 
| 
      
 158 
     | 
    
         
            +
                it 'should filter by Intersects' do
         
     | 
| 
      
 159 
     | 
    
         
            +
                  featured_for_posts(:intersecting, Date.new(2015,1,15) ).should == [@posts[0]]
         
     | 
| 
      
 160 
     | 
    
         
            +
                  featured_for_posts(:intersecting, 'January only').should == [@posts[0]]
         
     | 
| 
      
 161 
     | 
    
         
            +
                  featured_for_posts(:intersecting, 'January and February').should == @posts[0..1]
         
     | 
| 
      
 162 
     | 
    
         
            +
                  featured_for_posts(:intersecting, 'January and February', negated = true).should == [@posts[2]]
         
     | 
| 
      
 163 
     | 
    
         
            +
                  featured_for_posts(:intersecting, 'February only').should == [@posts[1]]
         
     | 
| 
      
 164 
     | 
    
         
            +
                  featured_for_posts(:intersecting, 'February only', negated = true).should == [@posts[0], @posts[2]]
         
     | 
| 
      
 165 
     | 
    
         
            +
                end
         
     | 
| 
      
 166 
     | 
    
         
            +
             
     | 
| 
      
 167 
     | 
    
         
            +
                it 'should filter by Within' do
         
     | 
| 
      
 168 
     | 
    
         
            +
                  featured_for_posts(:within, Date.new(2015,1,15) ).should be_empty
         
     | 
| 
      
 169 
     | 
    
         
            +
                  (date_ranges.keys - date_ranges.keys.grep(/ to /)).each do |key|
         
     | 
| 
      
 170 
     | 
    
         
            +
                    featured_for_posts(:within, key).should be_empty
         
     | 
| 
      
 171 
     | 
    
         
            +
                  end
         
     | 
| 
      
 172 
     | 
    
         
            +
                  featured_for_posts(:within, 'December to February').should == [@posts[0]]
         
     | 
| 
      
 173 
     | 
    
         
            +
                  featured_for_posts(:within, 'December to February', negated = true).should == @posts[1..-1]
         
     | 
| 
      
 174 
     | 
    
         
            +
                  featured_for_posts(:within, 'January to March').should == [@posts[1]]
         
     | 
| 
      
 175 
     | 
    
         
            +
                  featured_for_posts(:within, 'January to March', negated = true).should == [@posts[0], @posts[2]]
         
     | 
| 
      
 176 
     | 
    
         
            +
                  featured_for_posts(:within, 'December to March').should == @posts[0..1]
         
     | 
| 
      
 177 
     | 
    
         
            +
                  featured_for_posts(:within, 'December to March', negated = true).should == [@posts[2]]
         
     | 
| 
      
 178 
     | 
    
         
            +
                end
         
     | 
| 
      
 179 
     | 
    
         
            +
              end
         
     | 
| 
      
 180 
     | 
    
         
            +
             
     | 
| 
       130 
181 
     | 
    
         
             
              describe 'Boolean field type' do
         
     | 
| 
       131 
182 
     | 
    
         
             
                before :all do
         
     | 
| 
       132 
183 
     | 
    
         
             
                  Sunspot.remove_all
         
     | 
    
        data/spec/mocks/post.rb
    CHANGED
    
    | 
         @@ -3,7 +3,8 @@ require File.join(File.dirname(__FILE__), 'super_class') 
     | 
|
| 
       3 
3 
     | 
    
         | 
| 
       4 
4 
     | 
    
         
             
            class Post < SuperClass
         
     | 
| 
       5 
5 
     | 
    
         
             
              attr_accessor :title, :body, :blog_id, :published_at, :ratings_average,
         
     | 
| 
       6 
     | 
    
         
            -
                            :author_name, :featured, :expire_date, :coordinates, :tags
         
     | 
| 
      
 6 
     | 
    
         
            +
                            :author_name, :featured, :expire_date, :coordinates, :tags,
         
     | 
| 
      
 7 
     | 
    
         
            +
                            :featured_for
         
     | 
| 
       7 
8 
     | 
    
         
             
              alias_method :featured?, :featured
         
     | 
| 
       8 
9 
     | 
    
         | 
| 
       9 
10 
     | 
    
         
             
              def category_ids
         
     | 
| 
         @@ -43,6 +44,7 @@ Sunspot.setup(Post) do 
     | 
|
| 
       43 
44 
     | 
    
         
             
              float :average_rating, :using => :ratings_average, :trie => true
         
     | 
| 
       44 
45 
     | 
    
         
             
              time :published_at, :trie => true
         
     | 
| 
       45 
46 
     | 
    
         
             
              date :expire_date
         
     | 
| 
      
 47 
     | 
    
         
            +
              date_range :featured_for
         
     | 
| 
       46 
48 
     | 
    
         
             
              boolean :featured, :using => :featured?, :stored => true
         
     | 
| 
       47 
49 
     | 
    
         
             
              string :sort_title do
         
     | 
| 
       48 
50 
     | 
    
         
             
                title.downcase.sub(/^(a|an|the)\W+/, '') if title
         
     |