sunspot 1.1.0 → 1.2.0
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/Gemfile +10 -0
- data/Gemfile.lock +32 -0
- data/History.txt +24 -0
- data/README.rdoc +18 -5
- data/lib/sunspot.rb +40 -0
- data/lib/sunspot/dsl.rb +2 -2
- data/lib/sunspot/dsl/field_query.rb +2 -2
- data/lib/sunspot/dsl/fields.rb +0 -10
- data/lib/sunspot/dsl/restriction.rb +4 -4
- data/lib/sunspot/dsl/restriction_with_near.rb +121 -0
- data/lib/sunspot/dsl/scope.rb +55 -67
- data/lib/sunspot/dsl/standard_query.rb +11 -15
- data/lib/sunspot/field.rb +30 -29
- data/lib/sunspot/field_factory.rb +0 -18
- data/lib/sunspot/installer/solrconfig_updater.rb +0 -30
- data/lib/sunspot/query.rb +4 -3
- data/lib/sunspot/query/common_query.rb +2 -2
- data/lib/sunspot/query/composite_fulltext.rb +7 -2
- data/lib/sunspot/query/connective.rb +21 -6
- data/lib/sunspot/query/dismax.rb +1 -0
- data/lib/sunspot/query/geo.rb +53 -0
- data/lib/sunspot/query/more_like_this.rb +1 -0
- data/lib/sunspot/query/restriction.rb +5 -5
- data/lib/sunspot/query/standard_query.rb +0 -4
- data/lib/sunspot/search/abstract_search.rb +1 -7
- data/lib/sunspot/search/hit.rb +10 -10
- data/lib/sunspot/search/query_facet.rb +8 -3
- data/lib/sunspot/session.rb +10 -2
- data/lib/sunspot/session_proxy.rb +16 -0
- data/lib/sunspot/session_proxy/master_slave_session_proxy.rb +1 -1
- data/lib/sunspot/session_proxy/sharding_session_proxy.rb +7 -0
- data/lib/sunspot/session_proxy/silent_fail_session_proxy.rb +42 -0
- data/lib/sunspot/session_proxy/thread_local_session_proxy.rb +1 -1
- data/lib/sunspot/setup.rb +1 -17
- data/lib/sunspot/type.rb +38 -6
- data/lib/sunspot/util.rb +21 -31
- data/lib/sunspot/version.rb +1 -1
- data/solr/solr/conf/solrconfig.xml +0 -4
- data/spec/api/binding_spec.rb +12 -0
- data/spec/api/indexer/attributes_spec.rb +22 -22
- data/spec/api/query/connectives_examples.rb +14 -1
- data/spec/api/query/fulltext_examples.rb +3 -3
- data/spec/api/query/geo_examples.rb +69 -0
- data/spec/api/query/scope_examples.rb +32 -13
- data/spec/api/query/standard_spec.rb +1 -1
- data/spec/api/search/faceting_spec.rb +5 -1
- data/spec/api/search/hits_spec.rb +14 -12
- data/spec/api/session_proxy/class_sharding_session_proxy_spec.rb +1 -1
- data/spec/api/session_proxy/sharding_session_proxy_spec.rb +1 -1
- data/spec/api/session_proxy/silent_fail_session_proxy_spec.rb +24 -0
- data/spec/api/session_spec.rb +22 -0
- data/spec/integration/local_search_spec.rb +42 -69
- data/spec/integration/scoped_search_spec.rb +30 -0
- data/spec/mocks/connection.rb +6 -2
- data/spec/mocks/photo.rb +0 -1
- data/spec/mocks/post.rb +11 -2
- data/spec/mocks/user.rb +6 -1
- data/spec/spec_helper.rb +2 -12
- metadata +209 -177
- data/lib/sunspot/query/local.rb +0 -26
- data/solr/solr/lib/lucene-spatial-2.9.1.jar +0 -0
- data/solr/solr/lib/solr-spatial-light-0.0.6.jar +0 -0
- data/spec/api/query/local_examples.rb +0 -38
- data/tasks/gemspec.rake +0 -33
- data/tasks/rcov.rake +0 -28
- data/tasks/spec.rake +0 -24
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
sunspot (1.2.rc4)
|
5
|
+
escape (= 0.0.4)
|
6
|
+
pr_geohash (~> 1.0)
|
7
|
+
rsolr (= 0.12.1)
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: http://rubygems.org/
|
11
|
+
specs:
|
12
|
+
builder (3.0.0)
|
13
|
+
columnize (0.3.2)
|
14
|
+
escape (0.0.4)
|
15
|
+
linecache (0.43)
|
16
|
+
pr_geohash (1.0.0)
|
17
|
+
rsolr (0.12.1)
|
18
|
+
builder (>= 2.1.2)
|
19
|
+
rspec (1.3.0)
|
20
|
+
ruby-debug (0.10.3)
|
21
|
+
columnize (>= 0.1)
|
22
|
+
ruby-debug-base (~> 0.10.3.0)
|
23
|
+
ruby-debug-base (0.10.3)
|
24
|
+
linecache (>= 0.3)
|
25
|
+
|
26
|
+
PLATFORMS
|
27
|
+
ruby
|
28
|
+
|
29
|
+
DEPENDENCIES
|
30
|
+
rspec (~> 1.3)
|
31
|
+
ruby-debug
|
32
|
+
sunspot (= 1.2.rc4)!
|
data/History.txt
CHANGED
@@ -1,3 +1,27 @@
|
|
1
|
+
== 1.2.0 2010-12-28
|
2
|
+
* Replace solr-spatial-light with client-side geohash-based spatial search
|
3
|
+
* Override Solr field naming conventions using :as option
|
4
|
+
* Delegate #id method directly to calling context inside DSL
|
5
|
+
* Create a SilentFailSessionProxy that rescues exceptions on write operations.
|
6
|
+
* Inclusion by identity
|
7
|
+
* Solr optimize command
|
8
|
+
* Ignore negative :limit option for query facets
|
9
|
+
* Eliminated value sorting for range scopes
|
10
|
+
* Correctly cast stored boolean values if they are booleans
|
11
|
+
* Correctly cast and return stored values for multi-valued fields
|
12
|
+
|
13
|
+
== 1.1.0 2010-04-01
|
14
|
+
* MoreLikeThis support
|
15
|
+
* Allow multiple fulltext queries in one search
|
16
|
+
* Function queries
|
17
|
+
* Update solr-spatial-light to 0.0.6 build
|
18
|
+
* Support for :prefix when faceting.
|
19
|
+
* Allow specification of solr jar
|
20
|
+
* Updated reindex task to allow setting of batch size and list of models to index
|
21
|
+
* Use a '*:*' query for deleting the entire index
|
22
|
+
* Ability to specify custom request handler for queries
|
23
|
+
* Gracefully handle nonexistent search result
|
24
|
+
|
1
25
|
== 1.0.4 2010-03-19
|
2
26
|
* Update solr-spatial-light to 0.0.5
|
3
27
|
* Fix NullPointerException in repeated geo search
|
data/README.rdoc
CHANGED
@@ -63,7 +63,7 @@ field name patterns defined in the packaged <code>schema.xml</code>, so those
|
|
63
63
|
cannot be modified.
|
64
64
|
|
65
65
|
You can also run your own instance of Solr wherever you'd like; just copy the solr/config/schema.xml file out of the gem's solr into your installation.
|
66
|
-
You can change the URL at which Sunspot accesses Solr
|
66
|
+
You can change the URL at which Sunspot accesses Solr by setting <code>SOLR_URL</code> in your application's environment, or assigning it to Sunspot's configuration directly:
|
67
67
|
|
68
68
|
Sunspot.config.solr.url = 'http://solr.my.host:9818/solr'
|
69
69
|
|
@@ -84,7 +84,7 @@ See the README for that gem or the Sunspot Wiki for more information.
|
|
84
84
|
end
|
85
85
|
|
86
86
|
Sunspot.setup(Post) do
|
87
|
-
text :title, :
|
87
|
+
text :title, :description, :stored => true
|
88
88
|
string :author_name
|
89
89
|
integer :blog_id
|
90
90
|
integer :category_ids
|
@@ -106,8 +106,10 @@ to define your own. See Sunspot::Adapters for more information.
|
|
106
106
|
|
107
107
|
=== Search for objects:
|
108
108
|
|
109
|
-
search = Sunspot.search Post do
|
110
|
-
keywords 'great pizza'
|
109
|
+
@search = Sunspot.search Post do
|
110
|
+
keywords 'great pizza' do
|
111
|
+
hightlight :title, :description
|
112
|
+
end
|
111
113
|
with :author_name, 'Mark Twain'
|
112
114
|
with(:blog_id).any_of [2, 14]
|
113
115
|
with(:category_ids).all_of [4, 10]
|
@@ -143,7 +145,7 @@ See Sunspot.search for more information.
|
|
143
145
|
- if hit.score
|
144
146
|
%span.relevance== (#{hit.score})
|
145
147
|
%p= hit.highlight(:description).format { |word| "<span class=\"highlight\">#{word}</span>" }
|
146
|
-
.pagination= will_paginate(search.hits)
|
148
|
+
.pagination= will_paginate(@search.hits)
|
147
149
|
|
148
150
|
== About the API documentation
|
149
151
|
|
@@ -208,14 +210,20 @@ Sunspot repository at `upstream`:
|
|
208
210
|
* {Sunspot Full-text Search for Rails/Ruby}[http://therailworld.com/posts/23-Sunspot-Full-text-Search-for-Rails-Ruby] (The Rail World)
|
209
211
|
* {A Few Sunspot Tips}[http://blog.trydionel.com/2009/11/19/a-few-sunspot-tips/] (spiral_code)
|
210
212
|
* {Sunspot: A Solr-Powered Search Engine for Ruby}[http://www.linux-mag.com/id/7341] (Linux Magazine)
|
213
|
+
* {Sunspot Showed Me the Light}[http://bennyfreshness.com/2010/05/sunspot-helped-me-see-the-light/] (ben koonse)
|
214
|
+
* {rails3 + heroku + sunspot : madness}[http://anhaminha.tumblr.com/post/632682537/rails3-heroku-sunspot-madness] (anhaminha)
|
215
|
+
* {How to get full text search working with Sunspot}[http://cookbook.hobocentral.net/recipes/57-how-to-get-full-text-search] (Hobo Cookbook)
|
211
216
|
* {Using Sunspot for Free-Text Search with Redis}[http://masonoise.wordpress.com/2010/02/06/using-sunspot-for-free-text-search-with-redis/] (While I Pondered...)
|
217
|
+
* {Fuzzy searching in SOLR with Sunspot}[http://www.pipetodevnull.com/past/2010/8/5/fuzzy_searching_in_solr_with_sunspot/] (pipe :to => /dev/null)
|
212
218
|
* {Default scope with Sunspot}[http://www.cloudspace.com/blog/2010/01/15/default-scope-with-sunspot/] (Cloudspace)
|
213
219
|
* {Chef recipe for Sunspot in production}[http://gist.github.com/336403]
|
220
|
+
* {Cucumber and Sunspot}[http://opensoul.org/2010/4/7/cucumber-and-sunspot] (opensoul.org)
|
214
221
|
* {Testing Sunspot with Cucumber}[http://blog.trydionel.com/2010/02/06/testing-sunspot-with-cucumber/] (spiral_code)
|
215
222
|
* {Running cucumber features with sunspot_rails}[http://blog.kabisa.nl/2010/02/03/running-cucumber-features-with-sunspot_rails] (Kabisa Blog)
|
216
223
|
* {How To Use Twitter Lists to Determine Influence}[http://www.untitledstartup.com/2010/01/how-to-use-twitter-lists-to-determine-influence/] (Untitled Startup)
|
217
224
|
* {Sunspot Quickstart}[http://wiki.websolr.com/index.php/Sunspot_Quickstart] (WebSolr)
|
218
225
|
* {Solr, and Sunspot}[http://www.kuahyeow.com/2009/08/solr-and-sunspot.html] (YT!)
|
226
|
+
* {The Saga of the Switch}[http://mrb.github.com/2010/04/08/the-saga-of-the-switch.html] (mrb -- includes comparison of Sunspot and Ultrasphinx)
|
219
227
|
|
220
228
|
== Contributors
|
221
229
|
|
@@ -233,6 +241,11 @@ Sunspot repository at `upstream`:
|
|
233
241
|
* Kieran Topping
|
234
242
|
* Nicolas Braem (nicolas.braem@gmail.com)
|
235
243
|
* Jeremy Ashkenas (jashkenas@gmail.com)
|
244
|
+
* Dylan Vaughn (dylanvaughn@yahoo.com)
|
245
|
+
* Brian Durand (brian@embellishedvisions.com)
|
246
|
+
* Sam Granieri (sam@samgranieri.com)
|
247
|
+
* Nick Zadrozny (nick@onemorecloud.com)
|
248
|
+
* Jason Ronallo (jronallo@gmail.com)
|
236
249
|
|
237
250
|
== License
|
238
251
|
|
data/lib/sunspot.rb
CHANGED
@@ -206,6 +206,18 @@ module Sunspot
|
|
206
206
|
session.commit
|
207
207
|
end
|
208
208
|
|
209
|
+
# Optimizes the index on the singletion session.
|
210
|
+
#
|
211
|
+
# Frequently adding and deleting documents to Solr, leaves the index in a
|
212
|
+
# fragmented state. The optimize command merges all index segments into
|
213
|
+
# a single segment and removes any deleted documents, making it faster to
|
214
|
+
# search. Since optimize rebuilds the index from scratch, it takes some
|
215
|
+
# time and requires double the space on the hard disk while it's rebuilding.
|
216
|
+
# Note that optimize also commits.
|
217
|
+
def optimize
|
218
|
+
session.optimize
|
219
|
+
end
|
220
|
+
|
209
221
|
#
|
210
222
|
# Create a new Search instance, but do not execute it immediately. Generally
|
211
223
|
# you will want to use the #search method to build and execute searches in
|
@@ -327,6 +339,34 @@ module Sunspot
|
|
327
339
|
session.new_more_like_this(object, *types, &block)
|
328
340
|
end
|
329
341
|
|
342
|
+
#
|
343
|
+
# Initiate a MoreLikeThis search. MoreLikeThis is a special type of search
|
344
|
+
# that finds similar documents using fulltext comparison. The fields to be
|
345
|
+
# compared are `text` fields set up with the `:more_like_this` option set to
|
346
|
+
# `true`. By default, more like this returns objects of the same type as the
|
347
|
+
# object used for comparison, but a list of types can optionally be passed
|
348
|
+
# to this method to return similar documents of other types. This will only
|
349
|
+
# work for types that have common fields.
|
350
|
+
#
|
351
|
+
# The DSL for MoreLikeThis search exposes several methods for setting
|
352
|
+
# options specific to this type of search. See the
|
353
|
+
# Sunspot::DSL::MoreLikeThis class and the MoreLikeThis documentation on
|
354
|
+
# the Solr wiki: http://wiki.apache.org/solr/MoreLikeThis
|
355
|
+
#
|
356
|
+
# MoreLikeThis searches have all of the same scoping, ordering, and faceting
|
357
|
+
# functionality as standard searches; the only thing you can't do in a MLT
|
358
|
+
# search is fulltext matching (since the MLT itself is a fulltext query).
|
359
|
+
#
|
360
|
+
# ==== Example
|
361
|
+
#
|
362
|
+
# post = Post.first
|
363
|
+
# Sunspot.more_like_this(post, Post, Page) do
|
364
|
+
# fields :title, :body
|
365
|
+
# with(:updated_at).greater_than(1.month.ago)
|
366
|
+
# facet(:category_ids)
|
367
|
+
# end
|
368
|
+
#
|
369
|
+
#
|
330
370
|
def more_like_this(object, *types, &block)
|
331
371
|
session.more_like_this(object, *types, &block)
|
332
372
|
end
|
data/lib/sunspot/dsl.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
%w(fields scope paginatable adjustable field_query standard_query query_facet
|
2
|
-
functional fulltext restriction search
|
3
|
-
function).each do |file|
|
2
|
+
functional fulltext restriction restriction_with_near search
|
3
|
+
more_like_this_query function).each do |file|
|
4
4
|
require File.join(File.dirname(__FILE__), 'dsl', file)
|
5
5
|
end
|
@@ -196,7 +196,7 @@ module Sunspot
|
|
196
196
|
search_facet = @search.add_field_facet(field, options)
|
197
197
|
Util.Array(options[:only]).each do |value|
|
198
198
|
facet = Sunspot::Query::QueryFacet.new
|
199
|
-
facet.
|
199
|
+
facet.add_positive_restriction(field, Sunspot::Query::Restriction::EqualTo, value)
|
200
200
|
@query.add_query_facet(facet)
|
201
201
|
search_facet.add_row(value, facet.to_boolean_phrase)
|
202
202
|
end
|
@@ -236,7 +236,7 @@ module Sunspot
|
|
236
236
|
nil
|
237
237
|
)
|
238
238
|
when :none
|
239
|
-
extra_facet.
|
239
|
+
extra_facet.add_positive_restriction(
|
240
240
|
field,
|
241
241
|
Sunspot::Query::Restriction::EqualTo,
|
242
242
|
nil
|
data/lib/sunspot/dsl/fields.rb
CHANGED
@@ -43,16 +43,6 @@ module Sunspot
|
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
46
|
-
#
|
47
|
-
# Specify a method or block that returns the geographical coordinates
|
48
|
-
# associated with the document. The object returned must respond to #first
|
49
|
-
# and #last (e.g., a two-element Array); or to #lat and one of #lng, #lon,
|
50
|
-
# or #long
|
51
|
-
#
|
52
|
-
def coordinates(name = nil, &block)
|
53
|
-
@setup.set_coordinates_field(name, &block)
|
54
|
-
end
|
55
|
-
|
56
46
|
#
|
57
47
|
# Specify a document-level boost. As with fields, you have the option of
|
58
48
|
# passing an attribute name which will be called on each model, or a block
|
@@ -8,15 +8,15 @@ module Sunspot
|
|
8
8
|
# restriction.
|
9
9
|
#
|
10
10
|
class Restriction
|
11
|
-
def initialize(
|
12
|
-
@
|
11
|
+
def initialize(field, scope, negative) #:nodoc:
|
12
|
+
@field, @scope, @negative = field, scope, negative
|
13
13
|
end
|
14
14
|
|
15
15
|
Sunspot::Query::Restriction.names.each do |class_name|
|
16
16
|
method_name = Util.snake_case(class_name.to_s)
|
17
17
|
module_eval(<<-RUBY, __FILE__, __LINE__ + 1)
|
18
|
-
def #{method_name}(value)
|
19
|
-
@scope.add_restriction(@
|
18
|
+
def #{method_name}(*value)
|
19
|
+
@scope.add_restriction(@negative, @field, Sunspot::Query::Restriction::#{class_name}, *value)
|
20
20
|
end
|
21
21
|
RUBY
|
22
22
|
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
module Sunspot
|
2
|
+
module DSL
|
3
|
+
class RestrictionWithNear < Restriction
|
4
|
+
def initialize(field, scope, query, negated)
|
5
|
+
super(field, scope, negated)
|
6
|
+
@query = query
|
7
|
+
end
|
8
|
+
|
9
|
+
#
|
10
|
+
# Perform a Geohash-based location restriction for the given `location`
|
11
|
+
# field. Though this uses the same API as other attribute-field
|
12
|
+
# restrictions, there are several differences between this and other
|
13
|
+
# scoping methods:
|
14
|
+
#
|
15
|
+
# * It can only be called from the top-level query; it cannot be nested
|
16
|
+
# in a `dynamic`, `any_of`, or `all_of` block. This is because geohash
|
17
|
+
# queries are not sent to Solr as filter queries like other scopes, but
|
18
|
+
# rather are part of the fulltext query sent to Solr.
|
19
|
+
# * Because it is included with the fulltext query (if any), location
|
20
|
+
# restrictions can be given boost. By default, an "exact"
|
21
|
+
# (maximum-precision) match will give the result a boost of 1.0; each
|
22
|
+
# lower level of precision gives a boost of 1/2 the next highest
|
23
|
+
# precision. See below for options to modify this behavior.
|
24
|
+
#
|
25
|
+
# ==== What is a Geohash?
|
26
|
+
#
|
27
|
+
# Geohash is a clever algorithm that creates a decodable digest of a
|
28
|
+
# geographical point. It does this by dividing the globe into
|
29
|
+
# quadrants, encoding the quadrant in which the point sits in the hash,
|
30
|
+
# dividing the quadrant into smaller quadrants, and repeating an arbitrary
|
31
|
+
# number of times (the "precision"). Because of the way Geohash are
|
32
|
+
# built, the shared Geohash prefix length of two locations will
|
33
|
+
# <em>usually</em> increase as the distance between the points decreases.
|
34
|
+
# Put another way, the geohashes of two nearby points will
|
35
|
+
# <em>usually</em> have a longer shared prefix than two points which are
|
36
|
+
# distant from one another.
|
37
|
+
#
|
38
|
+
# Read more about Geohashes on
|
39
|
+
# {Wikipedia}[http://en.wikipedia.org/wiki/Geohash] or play around with
|
40
|
+
# generating your own at {geohash.org}[http://geohash.org/].
|
41
|
+
#
|
42
|
+
# In Sunspot, GeoHashes can have a precision between 3 and 12; this is the
|
43
|
+
# number of characters in the hash. The precisions have the following
|
44
|
+
# maximum bounding box sizes, in miles:
|
45
|
+
#
|
46
|
+
# <dt>3</dt>
|
47
|
+
# <dd>389.07812</dd>
|
48
|
+
# <dt>4</dt>
|
49
|
+
# <dd>97.26953</dd>
|
50
|
+
# <dt>5</dt>
|
51
|
+
# <dd>24.31738</dd>
|
52
|
+
# <dt>6</dt>
|
53
|
+
# <dd>6.07935</dd>
|
54
|
+
# <dt>7</dt>
|
55
|
+
# <dd>1.51984
|
56
|
+
# <dt>8</dt>
|
57
|
+
# <dd>0.37996</dd>
|
58
|
+
# <dt>9</dt>
|
59
|
+
# <dd>0.09499</dd>
|
60
|
+
# <dt>10</dt>
|
61
|
+
# <dd>0.02375</dd>
|
62
|
+
# <dt>11</dt>
|
63
|
+
# <dd>0.00594</dd>
|
64
|
+
# <dt>12</dt>
|
65
|
+
# <dd>0.00148</dd>
|
66
|
+
#
|
67
|
+
# ==== Score, boost, and sorting with location search
|
68
|
+
#
|
69
|
+
# The concept of relevance scoring is a familiar one from fulltext search;
|
70
|
+
# Solr (or Lucene, actually) gives each result document a score based on
|
71
|
+
# how relevant the document's text is to the search phrase. Sunspot's
|
72
|
+
# location search also uses scoring to determine geographical relevance;
|
73
|
+
# using boosts, longer prefix matches (which are, in general,
|
74
|
+
# geographically closer to the search origin) are assigned higher
|
75
|
+
# relevance. This means that the results of a pure location search are
|
76
|
+
# <em>roughly</em> in order of geographical distance, as long as no other
|
77
|
+
# sort is specified explicitly.
|
78
|
+
#
|
79
|
+
# This geographical relevance plays on the same field as fulltext scoring;
|
80
|
+
# if you use both fulltext and geographical components in a single search,
|
81
|
+
# both types of relevance will be taken into account when scoring the
|
82
|
+
# matches. Thus, a very close fulltext match that's further away from the
|
83
|
+
# geographical origin will be scored similarly to a less precise fulltext
|
84
|
+
# match that is very close to the geographical origin. That's likely to be
|
85
|
+
# consistent with the way most users would expect a fulltext geographical
|
86
|
+
# search to work.
|
87
|
+
#
|
88
|
+
# ==== Options
|
89
|
+
#
|
90
|
+
# <dt><code>:precision</code></dt>
|
91
|
+
# <dd>The minimum precision at which locations should match. See the table
|
92
|
+
# of precisions and bounding-box sizes above; the proximity value will
|
93
|
+
# ensure that all matching documents share a bounding box of the
|
94
|
+
# corresponding maximum size with your origin point. The default value
|
95
|
+
# is 7, meaning all results will share a bounding box with edges of
|
96
|
+
# about one and a half miles with the origin.</dd>
|
97
|
+
# <dt><code>:boost</code></dt>
|
98
|
+
# <dd>The boost to apply to maximum-precision matches. Default is 1.0. You
|
99
|
+
# can use this option to adjust the weight given to geographic
|
100
|
+
# proximity versus fulltext matching, if you are doing both in a
|
101
|
+
# search.</dd>
|
102
|
+
# <dt><code>:precision_factor</code></dt>
|
103
|
+
# <dd>This option determines how much boost is applied to matches at lower
|
104
|
+
# precisions. The default value, 16.0, means that a match at precision
|
105
|
+
# N is 1/16 as relevant as a match at precision N+1 (this is consistent
|
106
|
+
# with the fact that each precision's bounding box is about sixteen
|
107
|
+
# times the size of the next highest precision.)</dd>
|
108
|
+
#
|
109
|
+
# ==== Example
|
110
|
+
#
|
111
|
+
# Sunspot.search(Post) do
|
112
|
+
# fulltext('pizza')
|
113
|
+
# with(:location).near(-40.0, -70.0, :boost => 2, :precision => 6)
|
114
|
+
# end
|
115
|
+
#
|
116
|
+
def near(lat, lng, options = {})
|
117
|
+
@query.fulltext.add_location(@field, lat, lng, options)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
data/lib/sunspot/dsl/scope.rb
CHANGED
@@ -15,24 +15,35 @@ module Sunspot
|
|
15
15
|
end
|
16
16
|
|
17
17
|
#
|
18
|
-
# Build a positive restriction.
|
19
|
-
#
|
20
|
-
# restriction
|
21
|
-
#
|
22
|
-
#
|
23
|
-
#
|
24
|
-
#
|
25
|
-
#
|
18
|
+
# Build a positive restriction. This method can take three forms: equality
|
19
|
+
# restriction, restriction by another restriction, or identity
|
20
|
+
# restriction.
|
21
|
+
# In the first two forms, the first argument is a field name. If only a
|
22
|
+
# field name is specified, this method returns another DSL object which
|
23
|
+
# presents methods for attaching various restriction types.
|
24
|
+
# With two arguments, this creates a shorthand restriction: if the second
|
25
|
+
# argument is a scalar, an equality restriction is created; if it is a
|
26
|
+
# Range, a between restriction will be created; and if it is an Array, an
|
27
|
+
# any_of restriction will be created.
|
28
|
+
# The third from restricts the search results to a specific instance.
|
29
|
+
#
|
30
|
+
# ==== Parameters (restriction by field value)
|
26
31
|
#
|
27
32
|
# field_name<Symbol>:: Name of the field on which to place the restriction
|
28
33
|
# value<Object,Range,Array>::
|
29
34
|
# If passed, creates an equality, range, or any-of restriction based on
|
30
35
|
# the type of value passed.
|
31
36
|
#
|
37
|
+
# ==== Parameters (restriction by identity)
|
38
|
+
#
|
39
|
+
# args<Object>...::
|
40
|
+
# One or more instances that should be included in the results
|
41
|
+
#
|
32
42
|
# ==== Returns
|
33
43
|
#
|
34
44
|
# Sunspot::DSL::Query::Restriction::
|
35
|
-
# Restriction DSL object (if only one argument is passed
|
45
|
+
# Restriction DSL object (if only one argument is passed which is a
|
46
|
+
# field name)
|
36
47
|
#
|
37
48
|
# ==== Examples
|
38
49
|
#
|
@@ -60,71 +71,22 @@ module Sunspot
|
|
60
71
|
# with(:average_rating).greater_than(3.0)
|
61
72
|
# end
|
62
73
|
#
|
63
|
-
|
64
|
-
if value == NONE
|
65
|
-
DSL::Restriction.new(@setup.field(field_name.to_sym), @scope, false)
|
66
|
-
else
|
67
|
-
@scope.add_shorthand_restriction(@setup.field(field_name), value)
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
#
|
72
|
-
# Build a negative restriction (exclusion). This method can take three
|
73
|
-
# forms: equality exclusion, exclusion by another restriction, or identity
|
74
|
-
# exclusion. The first two forms work the same way as the #with method;
|
75
|
-
# the third excludes a specific instance from the search results.
|
76
|
-
#
|
77
|
-
# ==== Parameters (exclusion by field value)
|
78
|
-
#
|
79
|
-
# field_name<Symbol>:: Name of the field on which to place the exclusion
|
80
|
-
# value<Symbol>::
|
81
|
-
# If passed, creates an equality exclusion with this value
|
82
|
-
#
|
83
|
-
# ==== Parameters (exclusion by identity)
|
84
|
-
#
|
85
|
-
# args<Object>...::
|
86
|
-
# One or more instances that should be excluded from the results
|
87
|
-
#
|
88
|
-
# ==== Examples
|
89
|
-
#
|
90
|
-
# An equality exclusion:
|
91
|
-
#
|
92
|
-
# Sunspot.search(Post) do
|
93
|
-
# without(:blog_id, 1)
|
94
|
-
# end
|
95
|
-
#
|
96
|
-
# Other restriction types:
|
74
|
+
# Restriction by identity:
|
97
75
|
#
|
98
76
|
# Sunspot.search(Post) do
|
99
|
-
#
|
77
|
+
# with(some_post_instance)
|
100
78
|
# end
|
101
79
|
#
|
102
|
-
|
80
|
+
def with(*args)
|
81
|
+
add_restriction(false, *args)
|
82
|
+
end
|
83
|
+
|
103
84
|
#
|
104
|
-
#
|
105
|
-
#
|
106
|
-
# end
|
85
|
+
# Build a negative restriction (exclusion). This method works the same way
|
86
|
+
# asthe #with method.
|
107
87
|
#
|
108
88
|
def without(*args)
|
109
|
-
|
110
|
-
when String, Symbol
|
111
|
-
field_name = args[0]
|
112
|
-
value = args.length > 1 ? args[1] : NONE
|
113
|
-
if value == NONE
|
114
|
-
DSL::Restriction.new(@setup.field(field_name.to_sym), @scope, true)
|
115
|
-
else
|
116
|
-
@scope.add_negated_shorthand_restriction(@setup.field(field_name.to_sym), value)
|
117
|
-
end
|
118
|
-
else
|
119
|
-
instances = args
|
120
|
-
instances.flatten.each do |instance|
|
121
|
-
@scope.add_negated_restriction(
|
122
|
-
IdField.instance,
|
123
|
-
Sunspot::Query::Restriction::EqualTo,
|
124
|
-
Sunspot::Adapters::InstanceAdapter.adapt(instance).index_id
|
125
|
-
)
|
126
|
-
end
|
127
|
-
end
|
89
|
+
add_restriction(true, *args)
|
128
90
|
end
|
129
91
|
|
130
92
|
#
|
@@ -224,6 +186,32 @@ module Sunspot
|
|
224
186
|
&block
|
225
187
|
)
|
226
188
|
end
|
189
|
+
|
190
|
+
private
|
191
|
+
|
192
|
+
def add_restriction(negated, *args)
|
193
|
+
case args.first
|
194
|
+
when String, Symbol
|
195
|
+
raise ArgumentError if args.length > 2
|
196
|
+
field_name = args[0]
|
197
|
+
value = args.length > 1 ? args[1] : NONE
|
198
|
+
if value == NONE
|
199
|
+
DSL::Restriction.new(@setup.field(field_name.to_sym), @scope, negated)
|
200
|
+
else
|
201
|
+
@scope.add_shorthand_restriction(negated, @setup.field(field_name.to_sym), value)
|
202
|
+
end
|
203
|
+
else
|
204
|
+
instances = args.flatten
|
205
|
+
@scope.add_restriction(
|
206
|
+
negated,
|
207
|
+
IdField.instance,
|
208
|
+
Sunspot::Query::Restriction::AnyOf,
|
209
|
+
instances.flatten.map { |instance|
|
210
|
+
Sunspot::Adapters::InstanceAdapter.adapt(instance).index_id }
|
211
|
+
)
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
227
215
|
end
|
228
216
|
end
|
229
217
|
end
|