sunspot 1.0.1 → 1.0.2
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.
- data/History.txt +6 -0
- data/lib/sunspot/query/restriction.rb +7 -0
- data/lib/sunspot/query/sort.rb +0 -10
- data/lib/sunspot/search.rb +27 -14
- data/lib/sunspot/search/hit.rb +2 -2
- data/lib/sunspot/server.rb +2 -2
- data/lib/sunspot/util.rb +4 -4
- data/lib/sunspot/version.rb +1 -1
- data/solr/solr/lib/solr-spatial-light-0.0.4.jar +0 -0
- data/spec/api/query/ordering_pagination_spec.rb +8 -0
- data/spec/api/query/scope_spec.rb +7 -0
- data/spec/api/search/faceting_spec.rb +11 -0
- data/spec/api/search/hits_spec.rb +5 -1
- data/spec/integration/local_search_spec.rb +17 -0
- data/spec/integration/scoped_search_spec.rb +9 -0
- data/spec/mocks/connection.rb +1 -1
- data/tasks/rdoc.rake +1 -1
- metadata +4 -4
- data/solr/solr/lib/solr-spatial-light-0.0.3.jar +0 -0
    
        data/History.txt
    CHANGED
    
    | @@ -1,3 +1,9 @@ | |
| 1 | 
            +
            == 1.0.2 2010-03-11
         | 
| 2 | 
            +
            * Restore Hit#distance for result geo distance
         | 
| 3 | 
            +
            * Remove :distance special sort
         | 
| 4 | 
            +
            * Quote reserved keywords in boolean queries
         | 
| 5 | 
            +
            * Add Search#facets accessor to retrieve all facets
         | 
| 6 | 
            +
             | 
| 1 7 | 
             
            == 1.0.1 2010-03-05
         | 
| 2 8 | 
             
            * Copy all needed config files when sunspot-installer run with force option
         | 
| 3 9 |  | 
| @@ -40,6 +40,8 @@ module Sunspot | |
| 40 40 | 
             
                    include Filter
         | 
| 41 41 | 
             
                    include RSolr::Char
         | 
| 42 42 |  | 
| 43 | 
            +
                    RESERVED_WORDS = Set['AND', 'OR', 'NOT']
         | 
| 44 | 
            +
             | 
| 43 45 | 
             
                    def initialize(field, value, negated = false)
         | 
| 44 46 | 
             
                      @field, @value, @negated = field, value, negated
         | 
| 45 47 | 
             
                    end
         | 
| @@ -133,6 +135,11 @@ module Sunspot | |
| 133 135 | 
             
                    #
         | 
| 134 136 | 
             
                    def solr_value(value = @value)
         | 
| 135 137 | 
             
                      solr_value = escape(@field.to_indexed(value))
         | 
| 138 | 
            +
                      if RESERVED_WORDS.include?(solr_value)
         | 
| 139 | 
            +
                        %Q("#{solr_value}")
         | 
| 140 | 
            +
                      else
         | 
| 141 | 
            +
                        solr_value
         | 
| 142 | 
            +
                      end
         | 
| 136 143 | 
             
                    end
         | 
| 137 144 | 
             
                  end
         | 
| 138 145 |  | 
    
        data/lib/sunspot/query/sort.rb
    CHANGED
    
    | @@ -90,16 +90,6 @@ module Sunspot | |
| 90 90 | 
             
                      "score #{direction_for_solr}"
         | 
| 91 91 | 
             
                    end
         | 
| 92 92 | 
             
                  end
         | 
| 93 | 
            -
             | 
| 94 | 
            -
                  # 
         | 
| 95 | 
            -
                  # A DistanceSort sorts by distance from the origin coordinates of a
         | 
| 96 | 
            -
                  # geographical distance search.
         | 
| 97 | 
            -
                  #
         | 
| 98 | 
            -
                  class DistanceSort < Abstract
         | 
| 99 | 
            -
                    def to_param
         | 
| 100 | 
            -
                      "geo_distance #{direction_for_solr}"
         | 
| 101 | 
            -
                    end
         | 
| 102 | 
            -
                  end
         | 
| 103 93 | 
             
                end
         | 
| 104 94 | 
             
              end
         | 
| 105 95 | 
             
            end
         | 
    
        data/lib/sunspot/search.rb
    CHANGED
    
    | @@ -11,16 +11,18 @@ module Sunspot | |
| 11 11 | 
             
              # Sunspot.new_search methods.
         | 
| 12 12 | 
             
              #
         | 
| 13 13 | 
             
              class Search
         | 
| 14 | 
            -
                 | 
| 15 | 
            -
                #  | 
| 16 | 
            -
                #  | 
| 17 | 
            -
                #  | 
| 18 | 
            -
                 | 
| 14 | 
            +
                attr_reader :query #:nodoc:
         | 
| 15 | 
            +
                # 
         | 
| 16 | 
            +
                # Retrieve all facet objects defined for this search, in order they were
         | 
| 17 | 
            +
                # defined. To retrieve an individual facet by name, use #facet()
         | 
| 18 | 
            +
                #
         | 
| 19 | 
            +
                attr_reader :facets
         | 
| 19 20 |  | 
| 20 21 | 
             
                def initialize(connection, setup, query, configuration) #:nodoc:
         | 
| 21 22 | 
             
                  @connection, @setup, @query = connection, setup, query
         | 
| 22 23 | 
             
                  @query.paginate(1, configuration.pagination.default_per_page)
         | 
| 23 | 
            -
                  @facets =  | 
| 24 | 
            +
                  @facets = []
         | 
| 25 | 
            +
                  @facets_by_name = {}
         | 
| 24 26 | 
             
                end
         | 
| 25 27 |  | 
| 26 28 | 
             
                #
         | 
| @@ -78,7 +80,7 @@ module Sunspot | |
| 78 80 | 
             
                    @hits ||=
         | 
| 79 81 | 
             
                      maybe_will_paginate(
         | 
| 80 82 | 
             
                        solr_response['docs'].map do |doc|
         | 
| 81 | 
            -
                          Hit.new(doc, highlights_for(doc), self)
         | 
| 83 | 
            +
                          Hit.new(doc, highlights_for(doc), distance_for(doc), self)
         | 
| 82 84 | 
             
                        end
         | 
| 83 85 | 
             
                      )
         | 
| 84 86 | 
             
                  end
         | 
| @@ -153,9 +155,9 @@ module Sunspot | |
| 153 155 | 
             
                def facet(name, dynamic_name = nil)
         | 
| 154 156 | 
             
                  if name
         | 
| 155 157 | 
             
                    if dynamic_name
         | 
| 156 | 
            -
                      @ | 
| 158 | 
            +
                      @facets_by_name[:"#{name}:#{dynamic_name}"]
         | 
| 157 159 | 
             
                    else
         | 
| 158 | 
            -
                      @ | 
| 160 | 
            +
                      @facets_by_name[name.to_sym]
         | 
| 159 161 | 
             
                    end
         | 
| 160 162 | 
             
                  end
         | 
| 161 163 | 
             
                end
         | 
| @@ -223,17 +225,17 @@ module Sunspot | |
| 223 225 | 
             
                end
         | 
| 224 226 |  | 
| 225 227 | 
             
                def add_field_facet(field, options = {}) #:nodoc:
         | 
| 226 | 
            -
                  name = (options[:name] || field.name) | 
| 227 | 
            -
                   | 
| 228 | 
            +
                  name = (options[:name] || field.name)
         | 
| 229 | 
            +
                  add_facet(name, FieldFacet.new(field, self, options))
         | 
| 228 230 | 
             
                end
         | 
| 229 231 |  | 
| 230 232 | 
             
                def add_date_facet(field, options) #:nodoc:
         | 
| 231 | 
            -
                  name = (options[:name] || field.name) | 
| 232 | 
            -
                   | 
| 233 | 
            +
                  name = (options[:name] || field.name)
         | 
| 234 | 
            +
                  add_facet(name, DateFacet.new(field, self, options))
         | 
| 233 235 | 
             
                end
         | 
| 234 236 |  | 
| 235 237 | 
             
                def add_query_facet(name, options) #:nodoc:
         | 
| 236 | 
            -
                   | 
| 238 | 
            +
                  add_facet(name, QueryFacet.new(name, self, options))
         | 
| 237 239 | 
             
                end
         | 
| 238 240 |  | 
| 239 241 | 
             
                def facet_response #:nodoc:
         | 
| @@ -256,6 +258,12 @@ module Sunspot | |
| 256 258 | 
             
                  end
         | 
| 257 259 | 
             
                end
         | 
| 258 260 |  | 
| 261 | 
            +
                def distance_for(doc)
         | 
| 262 | 
            +
                  if @solr_result['distances']
         | 
| 263 | 
            +
                    @solr_result['distances'][doc['id']]
         | 
| 264 | 
            +
                  end
         | 
| 265 | 
            +
                end
         | 
| 266 | 
            +
             | 
| 259 267 | 
             
                def verified_hits
         | 
| 260 268 | 
             
                  @verified_hits ||= maybe_will_paginate(hits.select { |hit| hit.instance })
         | 
| 261 269 | 
             
                end
         | 
| @@ -274,5 +282,10 @@ module Sunspot | |
| 274 282 | 
             
                def reset
         | 
| 275 283 | 
             
                  @results = @hits = @verified_hits = @total = @solr_response = @doc_ids = nil
         | 
| 276 284 | 
             
                end
         | 
| 285 | 
            +
             | 
| 286 | 
            +
                def add_facet(name, facet)
         | 
| 287 | 
            +
                  @facets << facet
         | 
| 288 | 
            +
                  @facets_by_name[name.to_sym] = facet
         | 
| 289 | 
            +
                end
         | 
| 277 290 | 
             
              end
         | 
| 278 291 | 
             
            end
         | 
    
        data/lib/sunspot/search/hit.rb
    CHANGED
    
    | @@ -30,10 +30,10 @@ module Sunspot | |
| 30 30 |  | 
| 31 31 | 
             
                  attr_writer :result #:nodoc:
         | 
| 32 32 |  | 
| 33 | 
            -
                  def initialize(raw_hit, highlights, search) #:nodoc:
         | 
| 33 | 
            +
                  def initialize(raw_hit, highlights, distance, search) #:nodoc:
         | 
| 34 34 | 
             
                    @class_name, @primary_key = *raw_hit['id'].match(/([^ ]+) (.+)/)[1..2]
         | 
| 35 35 | 
             
                    @score = raw_hit['score']
         | 
| 36 | 
            -
                    @distance =  | 
| 36 | 
            +
                    @distance = distance
         | 
| 37 37 | 
             
                    @search = search
         | 
| 38 38 | 
             
                    @stored_values = raw_hit
         | 
| 39 39 | 
             
                    @stored_cache = {}
         | 
    
        data/lib/sunspot/server.rb
    CHANGED
    
    | @@ -2,8 +2,8 @@ require 'escape' | |
| 2 2 | 
             
            require 'set'
         | 
| 3 3 | 
             
            require 'tempfile'
         | 
| 4 4 |  | 
| 5 | 
            -
            module Sunspot | 
| 6 | 
            -
              class Server
         | 
| 5 | 
            +
            module Sunspot
         | 
| 6 | 
            +
              class Server #:nodoc:
         | 
| 7 7 | 
             
                # Raised if #stop is called but the server is not running
         | 
| 8 8 | 
             
                ServerError = Class.new(RuntimeError)
         | 
| 9 9 | 
             
                AlreadyRunningError = Class.new(ServerError)
         | 
    
        data/lib/sunspot/util.rb
    CHANGED
    
    | @@ -187,8 +187,8 @@ module Sunspot | |
| 187 187 | 
             
                  end
         | 
| 188 188 |  | 
| 189 189 | 
             
                  def lat
         | 
| 190 | 
            -
                    if @coords.respond_to?(: | 
| 191 | 
            -
                      @coords | 
| 190 | 
            +
                    if @coords.respond_to?(:first)
         | 
| 191 | 
            +
                      @coords.first
         | 
| 192 192 | 
             
                    elsif @coords.respond_to?(:lat)
         | 
| 193 193 | 
             
                      @coords.lat
         | 
| 194 194 | 
             
                    else
         | 
| @@ -197,8 +197,8 @@ module Sunspot | |
| 197 197 | 
             
                  end
         | 
| 198 198 |  | 
| 199 199 | 
             
                  def lng
         | 
| 200 | 
            -
                    if @coords.respond_to?(: | 
| 201 | 
            -
                      @coords | 
| 200 | 
            +
                    if @coords.respond_to?(:last)
         | 
| 201 | 
            +
                      @coords.last
         | 
| 202 202 | 
             
                    elsif @coords.respond_to?(:lng)
         | 
| 203 203 | 
             
                      @coords.lng
         | 
| 204 204 | 
             
                    elsif @coords.respond_to?(:lon)
         | 
    
        data/lib/sunspot/version.rb
    CHANGED
    
    
| Binary file | 
| @@ -71,6 +71,14 @@ describe 'ordering and pagination' do | |
| 71 71 | 
             
                end.should raise_error(ArgumentError)
         | 
| 72 72 | 
             
              end
         | 
| 73 73 |  | 
| 74 | 
            +
              it 'throws an UnrecognizedFieldError if :distance is given for sort' do
         | 
| 75 | 
            +
                lambda do
         | 
| 76 | 
            +
                  session.search Post do
         | 
| 77 | 
            +
                    order_by :distance, :asc
         | 
| 78 | 
            +
                  end
         | 
| 79 | 
            +
                end.should raise_error(Sunspot::UnrecognizedFieldError)
         | 
| 80 | 
            +
              end
         | 
| 81 | 
            +
             | 
| 74 82 | 
             
              it 'does not allow ordering by multiple-value fields' do
         | 
| 75 83 | 
             
                lambda do
         | 
| 76 84 | 
             
                  session.search Post do
         | 
| @@ -15,6 +15,13 @@ describe 'scoped query', :type => :query do | |
| 15 15 | 
             
                connection.should have_last_search_including(:fq, 'title_ss:My\ Pet\ Post')
         | 
| 16 16 | 
             
              end
         | 
| 17 17 |  | 
| 18 | 
            +
              it 'scopes by exact match with a special string' do
         | 
| 19 | 
            +
                session.search Post do
         | 
| 20 | 
            +
                  with :title, 'OR'
         | 
| 21 | 
            +
                end
         | 
| 22 | 
            +
                connection.should have_last_search_including(:fq, 'title_ss:"OR"')
         | 
| 23 | 
            +
              end
         | 
| 24 | 
            +
             | 
| 18 25 | 
             
              it 'scopes by exact match with time' do
         | 
| 19 26 | 
             
                time = Time.parse('1983-07-08 05:00:00 -0400')
         | 
| 20 27 | 
             
                session.search Post do
         | 
| @@ -17,6 +17,17 @@ describe 'faceting', :type => :search do | |
| 17 17 | 
             
                result.facet('title').field_name.should == :title
         | 
| 18 18 | 
             
              end
         | 
| 19 19 |  | 
| 20 | 
            +
              it 'returns all facets specified by search' do
         | 
| 21 | 
            +
                stub_facet(:title_ss, { 'Author 1' => 1 })
         | 
| 22 | 
            +
                stub_facet(:blog_id_i, { '1' => 3 })
         | 
| 23 | 
            +
                result = session.search(Post) do
         | 
| 24 | 
            +
                  facet :title
         | 
| 25 | 
            +
                  facet :blog_id
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
                result.facets.first.field_name.should == :title
         | 
| 28 | 
            +
                result.facets.last.field_name.should == :blog_id
         | 
| 29 | 
            +
              end
         | 
| 30 | 
            +
             | 
| 20 31 | 
             
              it 'returns string facet' do
         | 
| 21 32 | 
             
                stub_facet(:title_ss, 'Author 1' => 2, 'Author 2' => 1)
         | 
| 22 33 | 
             
                result = session.search Post do
         | 
| @@ -123,7 +123,11 @@ describe 'hits', :type => :search do | |
| 123 123 | 
             
              end
         | 
| 124 124 |  | 
| 125 125 | 
             
              it 'should return geo distance' do
         | 
| 126 | 
            -
                 | 
| 126 | 
            +
                post = Post.new
         | 
| 127 | 
            +
                stub_results(post)
         | 
| 128 | 
            +
                connection.response['distances'] = {
         | 
| 129 | 
            +
                  "Post #{post.id}" => 1.23
         | 
| 130 | 
            +
                }
         | 
| 127 131 | 
             
                session.search(Post).hits.first.distance.should == 1.23
         | 
| 128 132 | 
             
              end
         | 
| 129 133 |  | 
| @@ -47,6 +47,14 @@ describe 'local search' do | |
| 47 47 | 
             
                end
         | 
| 48 48 | 
             
                search.results.should == [@posts[1]]
         | 
| 49 49 | 
             
              end
         | 
| 50 | 
            +
             | 
| 51 | 
            +
              it 'should perform a radial search with attribute scoping and distance sorting' do
         | 
| 52 | 
            +
                search = Sunspot.search(Post) do |query|
         | 
| 53 | 
            +
                  query.near(ORIGIN, :sort => true)
         | 
| 54 | 
            +
                  query.with(:title, 'teacup')
         | 
| 55 | 
            +
                end
         | 
| 56 | 
            +
                search.results.should == [@posts[1], @posts[4]]
         | 
| 57 | 
            +
              end
         | 
| 50 58 |  | 
| 51 59 | 
             
              it 'should order by arbitrary field' do
         | 
| 52 60 | 
             
                search = Sunspot.search(Post) do |query|
         | 
| @@ -71,4 +79,13 @@ describe 'local search' do | |
| 71 79 | 
             
                  end
         | 
| 72 80 | 
             
                end.should_not raise_error
         | 
| 73 81 | 
             
              end
         | 
| 82 | 
            +
             | 
| 83 | 
            +
              it 'should return geographical distance from origin' do
         | 
| 84 | 
            +
                search = Sunspot.search(Post) do |query|
         | 
| 85 | 
            +
                  query.near(ORIGIN, :sort => true)
         | 
| 86 | 
            +
                end
         | 
| 87 | 
            +
                search.hits.each do |hit|
         | 
| 88 | 
            +
                  hit.distance.should_not be_nil
         | 
| 89 | 
            +
                end
         | 
| 90 | 
            +
              end
         | 
| 74 91 | 
             
            end
         | 
| @@ -119,6 +119,15 @@ describe 'scoped_search' do | |
| 119 119 | 
             
                end
         | 
| 120 120 | 
             
              end
         | 
| 121 121 |  | 
| 122 | 
            +
              describe 'reserved words' do
         | 
| 123 | 
            +
                %w(AND OR NOT TO).each do |word|
         | 
| 124 | 
            +
                  it "should successfully search for #{word.inspect}" do
         | 
| 125 | 
            +
                    Sunspot.index!(post = Post.new(:title => word))
         | 
| 126 | 
            +
                    Sunspot.search(Post) { with(:title, word) }.results.should == [post]
         | 
| 127 | 
            +
                  end
         | 
| 128 | 
            +
                end
         | 
| 129 | 
            +
              end
         | 
| 130 | 
            +
             | 
| 122 131 | 
             
              describe 'passing nil value to equal' do
         | 
| 123 132 | 
             
                before :all do
         | 
| 124 133 | 
             
                  Sunspot.remove_all
         | 
    
        data/spec/mocks/connection.rb
    CHANGED
    
    
    
        data/tasks/rdoc.rake
    CHANGED
    
    | @@ -20,7 +20,7 @@ namespace :doc do | |
| 20 20 | 
             
              desc 'Generate rdoc and move into pages directory'
         | 
| 21 21 | 
             
              task :publish => :redoc do
         | 
| 22 22 | 
             
                doc_dir = File.join(File.dirname(__FILE__), '..', 'doc')
         | 
| 23 | 
            -
                publish_dir = File.join(File.dirname(__FILE__), '..', 'pages', 'docs')
         | 
| 23 | 
            +
                publish_dir = File.join(File.dirname(__FILE__), '..', '..', 'pages', 'docs')
         | 
| 24 24 | 
             
                FileUtils.rm_rf(publish_dir) if File.exist?(publish_dir)
         | 
| 25 25 | 
             
                FileUtils.cp_r(doc_dir, publish_dir)
         | 
| 26 26 | 
             
              end
         | 
    
        metadata
    CHANGED
    
    | @@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version | |
| 5 5 | 
             
              segments: 
         | 
| 6 6 | 
             
              - 1
         | 
| 7 7 | 
             
              - 0
         | 
| 8 | 
            -
              -  | 
| 9 | 
            -
              version: 1.0. | 
| 8 | 
            +
              - 2
         | 
| 9 | 
            +
              version: 1.0.2
         | 
| 10 10 | 
             
            platform: ruby
         | 
| 11 11 | 
             
            authors: 
         | 
| 12 12 | 
             
            - Mat Brown
         | 
| @@ -24,7 +24,7 @@ autorequire: | |
| 24 24 | 
             
            bindir: bin
         | 
| 25 25 | 
             
            cert_chain: []
         | 
| 26 26 |  | 
| 27 | 
            -
            date: 2010-03- | 
| 27 | 
            +
            date: 2010-03-11 00:00:00 -05:00
         | 
| 28 28 | 
             
            default_executable: 
         | 
| 29 29 | 
             
            dependencies: 
         | 
| 30 30 | 
             
            - !ruby/object:Gem::Dependency 
         | 
| @@ -246,8 +246,8 @@ files: | |
| 246 246 | 
             
            - solr/solr/conf/scripts.conf
         | 
| 247 247 | 
             
            - solr/solr/conf/schema.xml
         | 
| 248 248 | 
             
            - solr/solr/conf/stopwords.txt
         | 
| 249 | 
            +
            - solr/solr/lib/solr-spatial-light-0.0.4.jar
         | 
| 249 250 | 
             
            - solr/solr/lib/lucene-spatial-2.9.1.jar
         | 
| 250 | 
            -
            - solr/solr/lib/solr-spatial-light-0.0.3.jar
         | 
| 251 251 | 
             
            - solr/start.jar
         | 
| 252 252 | 
             
            has_rdoc: true
         | 
| 253 253 | 
             
            homepage: http://outoftime.github.com/sunspot
         | 
| Binary file |