mongoid_spacial 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +1 -0
- data/README.md +35 -2
- data/VERSION +1 -1
- data/lib/mongoid_spacial/contexts/mongo.rb +21 -16
- data/lib/mongoid_spacial/criterion.rb +2 -7
- data/lib/mongoid_spacial/field_option.rb +2 -2
- data/lib/mongoid_spacial/spacial/formulas.rb +0 -1
- data/lib/mongoid_spacial/spacial/geo_near_results.rb +123 -0
- data/lib/mongoid_spacial/spacial.rb +8 -5
- data/mongoid_spacial.gemspec +3 -2
- data/spec/functional/mongoid/contexts/mongo_spec.rb +18 -4
- data/spec/functional/mongoid/spacial/geo_near_results_spec.rb +45 -0
- data/spec/spec_helper.rb +4 -2
- metadata +4 -3
- data/lib/mongoid_spacial/spacial/geo_near.rb +0 -86
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -89,7 +89,6 @@ One of the most handy features we have added is geo_near finder
|
|
89
89
|
|
90
90
|
```ruby
|
91
91
|
# accepts all criteria chains except without, only, asc, desc, order\_by
|
92
|
-
# pagination does not work yet but will be added in the next version
|
93
92
|
River.where(:name=>'hudson').geo_near({:lat => 40.73083, :lng => -73.99756})
|
94
93
|
|
95
94
|
# geo\_near accepts a few parameters besides a point
|
@@ -99,13 +98,47 @@ River.where(:name=>'hudson').geo_near({:lat => 40.73083, :lng => -73.99756})
|
|
99
98
|
# :max\_distance - Integer
|
100
99
|
# :distance\_multiplier - Integer
|
101
100
|
# :spherical - true - To enable spherical calculations
|
101
|
+
River.geo_near([-73.99756,40.73083], :max_distance => 4, :unit => :mi, :spherical => true)
|
102
|
+
```
|
103
|
+
|
104
|
+
There are two types of pagination!
|
105
|
+
|
106
|
+
* MongoDB Pagination - Stores start of rows to page limit in memory
|
107
|
+
* Post Query Pagination - Stores all rows in memory
|
108
|
+
|
109
|
+
Post-Result is only minutely slower than MongoDB because MongoDB has to calculate distance for all of the rows anyway. The slow up is in the transfer of data from the database to ruby.
|
110
|
+
|
111
|
+
Post-Result has some advantages that are listed below.
|
112
|
+
|
113
|
+
```ruby
|
114
|
+
# MongoDB pagination
|
115
|
+
# overwrites #skip chain method
|
102
116
|
# :page - pagination will be enabled if set to any variable including nil, pagination will not be enabled if either :per\_page or :paginator is set
|
103
117
|
# :per\_page
|
104
118
|
# :paginator - Choose which paginator to use. [default :arrary]
|
105
119
|
# Prefered method to set is Mongoid::Spacial.paginator=:array
|
106
120
|
# Available Paginators [:kaminari, :will\_paginate, :array]
|
107
121
|
# The only thing this does really is configure default per\_page so it is only kind of useful
|
108
|
-
River.geo_near([-73.99756,40.73083], :
|
122
|
+
River.geo_near([-73.99756,40.73083], :page => 1)
|
123
|
+
```
|
124
|
+
|
125
|
+
```ruby
|
126
|
+
# Post Query Pagination
|
127
|
+
# At carzen we use Post Query Pagination because we need to re-sort our rows after fetching. Pagination is not friendly with re-sorting.
|
128
|
+
# You can jump pages continously without querying the database again.
|
129
|
+
# listens to #limit/:num & #skip before geo\_near
|
130
|
+
# #page(page\_number, opts = {})
|
131
|
+
# opts:
|
132
|
+
# :per\_page
|
133
|
+
# :paginator
|
134
|
+
# #per(per\_page\_number, opts = {})
|
135
|
+
# opts:
|
136
|
+
# :page
|
137
|
+
# :paginator
|
138
|
+
#
|
139
|
+
# both return a GeoNearResults, which is really just a modified Array
|
140
|
+
# #per really just #page but just moves the options around
|
141
|
+
River.geo_near([-73.99756,40.73083]).per(25).page(1)
|
109
142
|
```
|
110
143
|
|
111
144
|
Thanks
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
@@ -36,26 +36,31 @@ module Mongoid #:nodoc:
|
|
36
36
|
center = center.to_lng_lat if center.respond_to?(:to_lng_lat)
|
37
37
|
|
38
38
|
# set default opts
|
39
|
-
|
40
|
-
|
39
|
+
opts[:skip] ||= 0
|
40
|
+
|
41
|
+
if unit = Mongoid::Spacial.earth_radius[opts[:unit]]
|
42
|
+
opts[:unit] = (opts[:spherical]) ? unit : unit * Mongoid::Spacial::RAD_PER_DEG
|
41
43
|
end
|
44
|
+
|
45
|
+
opts[:distance_multiplier] = opts[:unit] if opts[:unit].kind_of?(Numeric)
|
42
46
|
|
43
47
|
# setup paging.
|
44
48
|
if opts.has_key?(:page)
|
45
49
|
opts[:page] ||= 1
|
46
50
|
opts[:paginator] ||= Mongoid::Spacial.paginator()
|
47
51
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
52
|
+
opts[:per_page] ||= case opts[:paginator]
|
53
|
+
when :will_paginate
|
54
|
+
@document.per_page
|
55
|
+
when :kaminari
|
56
|
+
Kaminari.config.default_per_page
|
57
|
+
else
|
58
|
+
Mongoid::Spacial.default_per_page
|
59
|
+
end
|
55
60
|
end
|
56
|
-
query = create_geo_near_query(center,opts)
|
57
|
-
results = klass.db.command(query)
|
58
|
-
Mongoid::Spacial::
|
61
|
+
opts[:query] = create_geo_near_query(center,opts)
|
62
|
+
results = klass.db.command(opts[:query])
|
63
|
+
Mongoid::Spacial::GeoNearResults.new(klass,results,opts)
|
59
64
|
end
|
60
65
|
|
61
66
|
private
|
@@ -69,11 +74,11 @@ module Mongoid #:nodoc:
|
|
69
74
|
|
70
75
|
# create limit and use skip
|
71
76
|
if opts[:num]
|
72
|
-
query['num'] =
|
77
|
+
query['num'] = opts[:skip] + opts[:num].to_i
|
73
78
|
elsif opts[:limit]
|
74
|
-
query['num'] =
|
79
|
+
query['num'] = opts[:skip] + opts[:limit]
|
75
80
|
elsif opts[:page]
|
76
|
-
query['num'] = (opts[:page] * opts[:per_page])
|
81
|
+
query['num'] = opts[:skip] +(opts[:page] * opts[:per_page])
|
77
82
|
end
|
78
83
|
|
79
84
|
# allow the use of complex werieis
|
@@ -85,7 +90,7 @@ module Mongoid #:nodoc:
|
|
85
90
|
|
86
91
|
if opts[:max_distance]
|
87
92
|
query['maxDistance'] = opts[:max_distance]
|
88
|
-
query['maxDistance'] = query['maxDistance']/opts[:
|
93
|
+
query['maxDistance'] = query['maxDistance']/opts[:unit] if opts[:unit]
|
89
94
|
end
|
90
95
|
|
91
96
|
if klass.db.connection.server_version >= '1.7'
|
@@ -1,8 +1,3 @@
|
|
1
1
|
require 'mongoid_spacial/criterion/complex'
|
2
|
-
|
3
|
-
|
4
|
-
module Criterion #:nodoc:
|
5
|
-
autoload :NearSpacial, 'mongoid_spacial/criterion/near_spacial'
|
6
|
-
autoload :WithinSpacial, 'mongoid_spacial/criterion/within_spacial'
|
7
|
-
end
|
8
|
-
end
|
2
|
+
require 'mongoid_spacial/criterion/near_spacial'
|
3
|
+
require 'mongoid_spacial/criterion/within_spacial'
|
@@ -4,8 +4,8 @@ field = (defined?(Mongoid::Field)) ? Mongoid::Field : Mongoid::Fields
|
|
4
4
|
|
5
5
|
field.option :spacial do |model,field,options|
|
6
6
|
options = {} unless options.kind_of?(Hash)
|
7
|
-
lat_meth = options[:lat] ||
|
8
|
-
lng_meth = options[:lng] ||
|
7
|
+
lat_meth = options[:lat] || :lat
|
8
|
+
lng_meth = options[:lng] || :lng
|
9
9
|
model.class_eval do
|
10
10
|
self.spacial_fields ||= []
|
11
11
|
self.spacial_fields << field.name.to_sym if self.spacial_fields.kind_of? Array
|
@@ -0,0 +1,123 @@
|
|
1
|
+
module Mongoid
|
2
|
+
module Spacial
|
3
|
+
class GeoNearResults < Array
|
4
|
+
attr_reader :stats, :document, :_original_array
|
5
|
+
attr_accessor :opts
|
6
|
+
|
7
|
+
def initialize(document,results,opts = {})
|
8
|
+
raise "class must include Mongoid::Spacial::Document" unless document.respond_to?(:spacial_fields_indexed)
|
9
|
+
@document = document
|
10
|
+
@opts = opts
|
11
|
+
@stats = results['stats'] || {}
|
12
|
+
@opts[:skip] ||= 0
|
13
|
+
@opts[:total_entries] = opts[:query]["num"] || @stats['nscanned']
|
14
|
+
@limit_value = opts[:per_page]
|
15
|
+
@current_page = opts[:page]
|
16
|
+
|
17
|
+
@_original_array = results['results'].collect do |result|
|
18
|
+
res = Mongoid::Factory.from_db(@document, result.delete('obj'))
|
19
|
+
res.geo = {}
|
20
|
+
# camel case is awkward in ruby when using variables...
|
21
|
+
if result['dis']
|
22
|
+
res.geo[:distance] = result.delete('dis').to_f
|
23
|
+
end
|
24
|
+
result.each do |key,value|
|
25
|
+
res.geo[key.snakecase.to_sym] = value
|
26
|
+
end
|
27
|
+
# dist_options[:formula] = opts[:formula] if opts[:formula]
|
28
|
+
@opts[:calculate] = @document.spacial_fields_indexed if @document.spacial_fields_indexed.kind_of?(Array) && @opts[:calculate] == true
|
29
|
+
if @opts[:calculate]
|
30
|
+
@opts[:calculate] = [@opts[:calculate]] unless @opts[:calculate].kind_of? Array
|
31
|
+
@opts[:calculate] = @opts[:calculate].map(&:to_sym) & geo_fields
|
32
|
+
if @document.spacial_fields_indexed.kind_of?(Array) && @document.spacial_fields_indexed.size == 1
|
33
|
+
primary = @document.spacial_fields_indexed.first
|
34
|
+
end
|
35
|
+
@opts[:calculate].each do |key|
|
36
|
+
key = (key.to_s+'_distance').to_sym
|
37
|
+
res.geo[key] = res.distance_from(key,center, @opts[:distance_multiplier])
|
38
|
+
res.geo[:distance] = res.geo[key] if primary && key == primary
|
39
|
+
end
|
40
|
+
end
|
41
|
+
res
|
42
|
+
end
|
43
|
+
|
44
|
+
if @opts[:page]
|
45
|
+
start = (@opts[:page]-1)*@opts[:per_page] # assuming current_page is 1 based.
|
46
|
+
super(@_original_array[@opts[:skip]+start, @opts[:per_page]] || [])
|
47
|
+
else
|
48
|
+
super(@_original_array[@opts[:skip]..-1] || [])
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def page(page, options = {})
|
53
|
+
new_collection = self.dup
|
54
|
+
|
55
|
+
options = self.opts.merge(options)
|
56
|
+
|
57
|
+
options[:page] = page || 1
|
58
|
+
|
59
|
+
options[:paginator] ||= Mongoid::Spacial.paginator()
|
60
|
+
|
61
|
+
options[:per_page] ||= case options[:paginator]
|
62
|
+
when :will_paginate
|
63
|
+
@document.per_page
|
64
|
+
when :kaminari
|
65
|
+
Kaminari.config.default_per_page
|
66
|
+
else
|
67
|
+
Mongoid::Spacial.default_per_page
|
68
|
+
end
|
69
|
+
|
70
|
+
|
71
|
+
start = (options[:page]-1)*options[:per_page] # assuming current_page is 1 based.
|
72
|
+
new_collection.replace(@_original_array[@opts[:skip]+start, options[:per_page]] || [])
|
73
|
+
|
74
|
+
new_collection.opts[:page] = options[:page]
|
75
|
+
new_collection.opts[:paginator] = options[:paginator]
|
76
|
+
new_collection.opts[:per_page] = options[:per_page]
|
77
|
+
|
78
|
+
new_collection
|
79
|
+
end
|
80
|
+
|
81
|
+
def per(num)
|
82
|
+
self.page(current_page, :per_page => num)
|
83
|
+
end
|
84
|
+
|
85
|
+
def total_entries
|
86
|
+
@opts[:total_entries]
|
87
|
+
end
|
88
|
+
|
89
|
+
def current_page
|
90
|
+
@opts[:page]
|
91
|
+
end
|
92
|
+
|
93
|
+
def limit_value
|
94
|
+
@opts[:per_page]
|
95
|
+
end
|
96
|
+
alias_method :per_page, :limit_value
|
97
|
+
|
98
|
+
def num_pages
|
99
|
+
@opts[:total_entries]/@opts[:per_page]
|
100
|
+
end
|
101
|
+
alias_method :total_pages, :num_pages
|
102
|
+
|
103
|
+
def out_of_bounds?
|
104
|
+
self.current_page > self.total_pages
|
105
|
+
end
|
106
|
+
|
107
|
+
def offset
|
108
|
+
(self.current_page - 1) * self.per_page
|
109
|
+
end
|
110
|
+
|
111
|
+
# current_page - 1 or nil if there is no previous page
|
112
|
+
def previous_page
|
113
|
+
self.current_page > 1 ? (self.current_page - 1) : nil
|
114
|
+
end
|
115
|
+
|
116
|
+
# current_page + 1 or nil if there is no next page
|
117
|
+
def next_page
|
118
|
+
self.current_page < self.total_pages ? (self.current_page + 1) : nil
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
@@ -1,9 +1,9 @@
|
|
1
1
|
require 'mongoid_spacial/spacial/core_ext'
|
2
2
|
require 'mongoid_spacial/spacial/formulas'
|
3
|
+
require 'mongoid_spacial/spacial/document'
|
4
|
+
require 'mongoid_spacial/spacial/geo_near_results'
|
3
5
|
module Mongoid
|
4
6
|
module Spacial
|
5
|
-
autoload :Document, 'mongoid_spacial/spacial/document'
|
6
|
-
autoload :GeoNear, 'mongoid_spacial/spacial/geo_near'
|
7
7
|
|
8
8
|
EARTH_RADIUS_KM = 6371 # taken directly from mongodb
|
9
9
|
|
@@ -14,15 +14,18 @@ module Mongoid
|
|
14
14
|
:ft => EARTH_RADIUS_KM*5280*0.621371192,
|
15
15
|
}
|
16
16
|
|
17
|
+
RAD_PER_DEG = Math::PI/180
|
18
|
+
|
17
19
|
LNG_SYMBOLS = [:x, :lon, :long, :lng, :longitude]
|
18
20
|
LAT_SYMBOLS = [:y, :lat, :latitude]
|
19
21
|
|
20
|
-
def distance(p1,p2,unit = nil, formula = nil)
|
22
|
+
def self.distance(p1,p2,unit = nil, formula = nil)
|
21
23
|
formula ||= self.distance_formula
|
22
24
|
unit = earth_radius[unit] if unit.kind_of?(Symbol) && earth_radius[unit]
|
23
25
|
rads = Formulas.send(formula, p1, p2)
|
24
26
|
(unit.kind_of?(Numeric)) ? unit*rads : rads
|
25
27
|
end
|
28
|
+
|
26
29
|
mattr_accessor :lng_symbols
|
27
30
|
@@lng_symbols = LNG_SYMBOLS.dup
|
28
31
|
|
@@ -35,8 +38,8 @@ module Mongoid
|
|
35
38
|
mattr_accessor :distance_formula
|
36
39
|
@@distance_formula = :n_vector
|
37
40
|
|
38
|
-
|
39
|
-
|
41
|
+
mattr_accessor :paginator
|
42
|
+
@@paginator = :array
|
40
43
|
|
41
44
|
mattr_accessor :default_per_page
|
42
45
|
@@default_per_page = 25
|
data/mongoid_spacial.gemspec
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{mongoid_spacial}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.2.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = [%q{Ryan Ong}]
|
@@ -40,12 +40,13 @@ Gem::Specification.new do |s|
|
|
40
40
|
"lib/mongoid_spacial/spacial/core_ext.rb",
|
41
41
|
"lib/mongoid_spacial/spacial/document.rb",
|
42
42
|
"lib/mongoid_spacial/spacial/formulas.rb",
|
43
|
-
"lib/mongoid_spacial/spacial/
|
43
|
+
"lib/mongoid_spacial/spacial/geo_near_results.rb",
|
44
44
|
"mongoid_spacial.gemspec",
|
45
45
|
"spec/config/mongod.conf",
|
46
46
|
"spec/config/mongoid.yml",
|
47
47
|
"spec/functional/mongoid/contexts/mongo_spec.rb",
|
48
48
|
"spec/functional/mongoid/criterion/inclusion_spec.rb",
|
49
|
+
"spec/functional/mongoid/spacial/geo_near_results_spec.rb",
|
49
50
|
"spec/models/account.rb",
|
50
51
|
"spec/models/acolyte.rb",
|
51
52
|
"spec/models/address.rb",
|
@@ -86,18 +86,18 @@ describe Mongoid::Contexts::Mongo do
|
|
86
86
|
Bar.delete_all
|
87
87
|
Bar.create_indexes
|
88
88
|
|
89
|
-
|
89
|
+
50.times do
|
90
90
|
Bar.create({:location => [rand(360)-180,rand(360)-180]})
|
91
91
|
end
|
92
92
|
end
|
93
93
|
context ":paginator :array" do
|
94
|
-
[nil,1,2
|
94
|
+
[nil,1,2].each do |page|
|
95
95
|
it "page=#{page} should have 25" do
|
96
96
|
Bar.geo_near([1,1], :page => page).size.should == 25
|
97
97
|
end
|
98
98
|
end
|
99
99
|
|
100
|
-
it "page=
|
100
|
+
it "page=3 should have 0" do
|
101
101
|
Bar.geo_near([1,1], :page => 20).size.should == 0
|
102
102
|
end
|
103
103
|
|
@@ -105,7 +105,21 @@ describe Mongoid::Contexts::Mongo do
|
|
105
105
|
Bar.geo_near([1,1], :page => 1, :per_page => 5).size.should == 5
|
106
106
|
end
|
107
107
|
end
|
108
|
+
|
109
|
+
context ":paginator :kaminari" do
|
110
|
+
let(:near) {Bar.geo_near([1,1], :page => 1)}
|
111
|
+
it "should have current_page" do
|
112
|
+
near.current_page.should == 1
|
113
|
+
end
|
114
|
+
|
115
|
+
it "should have num_pages" do
|
116
|
+
near.num_pages.should == 2
|
117
|
+
end
|
118
|
+
|
119
|
+
it "should have limit_value" do
|
120
|
+
near.limit_value.should == 25
|
121
|
+
end
|
122
|
+
end
|
108
123
|
end
|
109
124
|
|
110
125
|
end
|
111
|
-
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Mongoid::Spacial::GeoNearResults do
|
4
|
+
before(:all) do
|
5
|
+
Bar.delete_all
|
6
|
+
Bar.create_indexes
|
7
|
+
|
8
|
+
50.times do
|
9
|
+
Bar.create({:location => [rand(360)-180,rand(360)-180]})
|
10
|
+
end
|
11
|
+
while Bar.count < 50
|
12
|
+
end
|
13
|
+
end
|
14
|
+
context ":paginator :array" do
|
15
|
+
[nil,1,2].each do |page|
|
16
|
+
it "page=#{page} should have 25" do
|
17
|
+
Bar.geo_near([1,1]).page(page).size.should == 25
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
it "page=3 should have 0" do
|
22
|
+
Bar.geo_near([1,1]).page(3).size.should == 0
|
23
|
+
end
|
24
|
+
|
25
|
+
it "per=5" do
|
26
|
+
Bar.geo_near([1,1]).per(5).size.should == 5
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context ":paginator :kaminari" do
|
31
|
+
let!(:near) {Bar.geo_near([1,1]).page(1)}
|
32
|
+
it "should have current_page" do
|
33
|
+
near.current_page.should == 1
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should have num_pages" do
|
37
|
+
near.total_entries.should == 50
|
38
|
+
near.num_pages.should == 2
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should have limit_value" do
|
42
|
+
near.limit_value.should == 25
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -10,10 +10,13 @@ require "mongoid"
|
|
10
10
|
require "mocha"
|
11
11
|
require "rspec"
|
12
12
|
require "mongoid_spacial"
|
13
|
-
require 'ruby-debug'
|
14
13
|
|
15
14
|
LOGGER = Logger.new($stdout)
|
16
15
|
|
16
|
+
if RUBY_VERSION >= '1.9.2'
|
17
|
+
YAML::ENGINE.yamler = 'syck'
|
18
|
+
end
|
19
|
+
|
17
20
|
Mongoid.configure do |config|
|
18
21
|
name = "mongoid_spacial_test"
|
19
22
|
config.master = Mongo::Connection.new.db(name)
|
@@ -35,7 +38,6 @@ RSpec.configure do |config|
|
|
35
38
|
warn(Support::Authentication.message) unless user_configured
|
36
39
|
|
37
40
|
config.filter_run_excluding(:config => lambda { |value|
|
38
|
-
return true if value == :mongohq && !mongohq_configured
|
39
41
|
return true if value == :user && !user_configured
|
40
42
|
})
|
41
43
|
end
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: mongoid_spacial
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.
|
5
|
+
version: 0.2.0
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Ryan Ong
|
@@ -166,12 +166,13 @@ files:
|
|
166
166
|
- lib/mongoid_spacial/spacial/core_ext.rb
|
167
167
|
- lib/mongoid_spacial/spacial/document.rb
|
168
168
|
- lib/mongoid_spacial/spacial/formulas.rb
|
169
|
-
- lib/mongoid_spacial/spacial/
|
169
|
+
- lib/mongoid_spacial/spacial/geo_near_results.rb
|
170
170
|
- mongoid_spacial.gemspec
|
171
171
|
- spec/config/mongod.conf
|
172
172
|
- spec/config/mongoid.yml
|
173
173
|
- spec/functional/mongoid/contexts/mongo_spec.rb
|
174
174
|
- spec/functional/mongoid/criterion/inclusion_spec.rb
|
175
|
+
- spec/functional/mongoid/spacial/geo_near_results_spec.rb
|
175
176
|
- spec/models/account.rb
|
176
177
|
- spec/models/acolyte.rb
|
177
178
|
- spec/models/address.rb
|
@@ -261,7 +262,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
261
262
|
requirements:
|
262
263
|
- - ">="
|
263
264
|
- !ruby/object:Gem::Version
|
264
|
-
hash:
|
265
|
+
hash: -931697683295411699
|
265
266
|
segments:
|
266
267
|
- 0
|
267
268
|
version: "0"
|
@@ -1,86 +0,0 @@
|
|
1
|
-
module Mongoid
|
2
|
-
module Spacial
|
3
|
-
class GeoNear < Array
|
4
|
-
attr_reader :stats
|
5
|
-
|
6
|
-
def initialize(klass,results,opts = {})
|
7
|
-
raise "class must include Mongoid::Spacial::Document" unless klass.respond_to?(:spacial_fields_indexed)
|
8
|
-
@klass = klass
|
9
|
-
@opts = opts
|
10
|
-
@stats = results['stats']
|
11
|
-
|
12
|
-
@_original_array = results['results'].collect do |result|
|
13
|
-
res = Mongoid::Factory.from_db(klass, result.delete('obj'))
|
14
|
-
res.geo = {}
|
15
|
-
# camel case is awkward in ruby when using variables...
|
16
|
-
if result['dis']
|
17
|
-
res.geo[:distance] = result.delete('dis').to_f
|
18
|
-
end
|
19
|
-
result.each do |key,value|
|
20
|
-
res.geo[key.snakecase.to_sym] = value
|
21
|
-
end
|
22
|
-
# dist_options[:formula] = opts[:formula] if opts[:formula]
|
23
|
-
@opts[:calculate] = klass.spacial_fields_indexed if klass.spacial_fields_indexed.kind_of?(Array) && @opts[:calculate] == true
|
24
|
-
if @opts[:calculate]
|
25
|
-
@opts[:calculate] = [@opts[:calculate]] unless @opts[:calculate].kind_of? Array
|
26
|
-
@opts[:calculate] = @opts[:calculate].map(&:to_sym) & geo_fields
|
27
|
-
if klass.spacial_fields_indexed.kind_of?(Array) && klass.spacial_fields_indexed.size == 1
|
28
|
-
primary = klass.spacial_fields_indexed.first
|
29
|
-
end
|
30
|
-
@opts[:calculate].each do |key|
|
31
|
-
key = (key.to_s+'_distance').to_sym
|
32
|
-
res.geo[key] = res.distance_from(key,center, @opts[:distance_multiplier])
|
33
|
-
res.geo[:distance] = res.geo[key] if primary && key == primary
|
34
|
-
end
|
35
|
-
end
|
36
|
-
res
|
37
|
-
end
|
38
|
-
|
39
|
-
if @opts[:page]
|
40
|
-
start = (@opts[:page]-1)*@opts[:per_page] # assuming current_page is 1 based.
|
41
|
-
super(@_original_array[start, @opts[:per_page]] || [])
|
42
|
-
elsif @opts[:skip] && @_original_array.size > @opts[:skip]
|
43
|
-
super(@_original_array[@opts[:skip]..-1] || [])
|
44
|
-
else
|
45
|
-
super(@_original_array || [])
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
def current_page
|
50
|
-
@opts[:page]
|
51
|
-
end
|
52
|
-
|
53
|
-
def num_pages
|
54
|
-
@stats['nscanned']/@opts[:per_page]
|
55
|
-
end
|
56
|
-
alias_method :total_pages, :num_pages
|
57
|
-
|
58
|
-
def out_of_bounds?
|
59
|
-
current_page > total_pages
|
60
|
-
end
|
61
|
-
|
62
|
-
def limit_value
|
63
|
-
@opts[:per_page]
|
64
|
-
end
|
65
|
-
alias_method :per_page, :limit_value
|
66
|
-
|
67
|
-
def offset
|
68
|
-
(current_page - 1) * per_page
|
69
|
-
end
|
70
|
-
|
71
|
-
# current_page - 1 or nil if there is no previous page
|
72
|
-
def previous_page
|
73
|
-
current_page > 1 ? (current_page - 1) : nil
|
74
|
-
end
|
75
|
-
|
76
|
-
# current_page + 1 or nil if there is no next page
|
77
|
-
def next_page
|
78
|
-
current_page < total_pages ? (current_page + 1) : nil
|
79
|
-
end
|
80
|
-
|
81
|
-
def total_entries
|
82
|
-
@stats['nscanned']
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|