Как выполнить $ почти похожие запросы для массива пар lat / lng с mongomapper - PullRequest
0 голосов
/ 19 августа 2011

У меня есть модель поездки, которая содержит массив пар lat / lng

class Trip
  include MongoMapper::Document

  key :route, Array, # example: [[45,-122], [45.5, -122.5], [45, -123]]
  ...
end

Я бы хотел выполнить запросы типа $ near для массива маршрута, что должно быть возможно в соответствии с документацией .

Я бы хотел найти маршрут, ближайший к определенной точке.

def self.nearest_to(coords)
  where(:route => {'$near' => coords}).limit(1).first
end

Но это не работает, я получаю сообщение об ошибке:

Mongo::OperationFailure: can't find special index: 2d for: { route: { $near: [ 32.80909, -117.1537 ] } }
    from /Users/lash/.rvm/gems/ruby-1.9.2-p290@rails3.0.9/gems/mongo-1.3.1/lib/mongo/cursor.rb:101:in `next_document'
    from /Users/lash/.rvm/gems/ruby-1.9.2-p290@rails3.0.9/gems/mongo-1.3.1/lib/mongo/cursor.rb:248:in `each'
    from /Users/lash/.rvm/gems/ruby-1.9.2-p290@rails3.0.9/gems/mongo-1.3.1/lib/mongo/cursor.rb:267:in `to_a'
    from /Users/lash/.rvm/gems/ruby-1.9.2-p290@rails3.0.9/gems/mongo-1.3.1/lib/mongo/cursor.rb:267:in `to_a'
    from /Users/lash/.rvm/gems/ruby-1.9.2-p290@rails3.0.9/gems/plucky-0.3.8/lib/plucky/query.rb:76:in `all'
    from /Users/lash/code/rails3projects/rideshare/app/models/trip.rb:20:in `nearest'
    from (irb):10
    from /Users/lash/.rvm/gems/ruby-1.9.2-p290@rails3.0.9/gems/railties-3.0.9/lib/rails/commands/console.rb:44:in `start'
    from /Users/lash/.rvm/gems/ruby-1.9.2-p290@rails3.0.9/gems/railties-3.0.9/lib/rails/commands/console.rb:8:in `start'
    from /Users/lash/.rvm/gems/ruby-1.9.2-p290@rails3.0.9/gems/railties-3.0.9/lib/rails/commands.rb:23:in `<top (required)>'
    from script/rails:6:in `require'
    from script/rails:6:in `<main>'

Как правильно запрашивать документы с несколькими местоположениями с помощью mongomapper?

Ответы [ 2 ]

1 голос
/ 23 августа 2011

Правильный ответ - на сегодняшний день - это то, что вы не можете. Драйвер ruby ​​пока не поддерживает mongo 1.3.3, поэтому этот тип запроса геолокации просто невозможен.

Вот один пример того, как можно обойти проблему в это время.

class Trip
  include MongoMapper::Document

  key :route, Array # example: [[45,-122], [45.5, -122.5], [45, -123]]
  ...

  scope :passes_near, lambda {|coords| where(:id => {'$in' => Trip.near(coords)}) }

  def self.near(coords, options = {})
    options[:radius] ||= 60
    case coords
      when Array; coords
      when String; coords = Geocoder.coordinates(coords)
    end

    trips = {}
    Trip.all.each do |trip|
      dist = trip.route.map{|point| Geocoder::Calculations::distance_between(point, coords)}.min
      trips[trip.id] = dist
    end
    return trips.select {|k, v| v < options[:radius]}.keys
  end 
end 

Чтобы найти все поездки в Сиэтл ([47.6062095, -122.3320708]), я просто набрал:

Trip.passes_near("Seattle, WA") 
=> #<Plucky::Query _id: {"$in"=>[*lots of ids*}, transformer: #...> 

Поскольку возвращается отважный объект, было бы просто объединить запросы.

0 голосов
/ 19 августа 2011

В этом милом небольшом уроке вы найдете несколько ответов на сумму $:

...