【问题标题】:How to perform $near-like queries for array of lat/lng pairs with mongomapper如何使用 mongomapper 对 lat/lng 对的数组执行类似 $near 的查询
【发布时间】:2011-08-23 13:47:38
【问题描述】:

我有一个包含一组 lat/lng 对的行程模型

class Trip
  include MongoMapper::Document

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

我想对路由数组进行$near-type查询,根据documentation应该是可以的。

我想找到离某个点最近的路线。

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查询多位置文档的正确方法是什么?

【问题讨论】:

  • 您使用的是哪个版本的 MongoDB - 是 v1.3.3+
  • 不,根据我的捆绑器输出,它是 1.3.1。不过升级也没什么大不了的。
  • 快速浏览您链接的文档,看起来该功能需要 v1.3.3 或更高版本。不过,我没有使用 MongoDB 的第一手经验来支持这一点。
  • 好的,谢谢,我现在看到黄色警告三角了。
  • 我错了,这没什么大不了的。看起来 mongo ruby​​ 驱动程序还没有这个功能。

标签: mongodb mongomapper


【解决方案1】:

截至今天,正确答案是您不能。 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: #...> 

由于返回了一个 plucky 对象,因此将查询链接在一起很简单。

【讨论】:

    【解决方案2】:

    您应该在这个不错的小教程中找到有关 $near 的一些答案:http://mongly.com/

    db.treasures.find({location: {$near: [20, -20]}});
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-08-14
      • 2016-07-18
      • 1970-01-01
      • 1970-01-01
      • 2014-06-22
      • 2018-05-28
      • 2014-07-28
      相关资源
      最近更新 更多