使用 Mongoid 处理 MongoDB 在 Rails 中的地理空间索引。

15

MongoDB有一个非常不错的地理空间索引功能。我如何在Rails中使用它并与Mongoid配合?

3个回答

50

在mongoid中,您可以像这样定义地理索引

class Item
  include Mongoid::Document

  field :loc, :type => Array

  index(
      [
          [:loc, Mongo::GEO2D]             
      ], background: true

  )
end

关于查询

$near 命令(不带 maxDistance 参数)

 location = [80.24958300000003, 13.060422]
 items = Item.where(:loc => {"$near" => location})

$near 命令(带有 maxDistance 参数)

 distance = 10 #km
 location = [80.24958300000003, 13.060422]
 items = Item.where(:loc => {"$near" => location , '$maxDistance' => distance.fdiv(111.12)})

当使用公里时,通过111.12(一个经度大约是111.12公里)进行距离转换,或者在使用度数时保持距离不变。

$centerSphere / $nearSphere查询

location = [80.24958300000003, 13.060422]
items = Item.where(:loc => {"$within" => {"$centerSphere" => [location, (distance.fdiv(6371) )]}})

这将找到10公里半径内的物品。在这里,我们需要将距离/6371(地球半径)转换为公里,以使其运作。

$box(边界框查询)

 first_loc = [80.24958300000003, 13.060422]
 second_loc = [81.24958300000003, 12.060422]
 items = Item.where(:loc => {"$within" => {"$box" => [first_loc, second_loc]}})

这将帮助您在给定的边界框内查找物品。


当我尝试使用$near命令(带有maxDistance)时,它会返回一个错误:地理值必须是数字:{$maxDistance: 0.001799856011519079,$near: [80.249,13.060422]}有什么想法吗?如果只使用"$near",它可以工作,但是当我添加"$maxDistance"时,它就会出错。 - Vasily
@Vasily,我不确定...使用您指定的值,$near查询和$maxdistance完美地运行。Item.where(:loc => {"$near" => [ 80.249, 13.060422 ] , '$maxDistance' => 0.001799856011519079})。它很好用...也许您可以向我展示您尝试的查询?然后我们再看看。 - RameshVel
当我使用maxDistance时,我遇到了相同的错误。Ruby 1.8。你们找到解决方案了吗? - Mike Bevz

7

RameshVel的回答很好。

更新一下,在Mongoid 3.0.4中,我必须按照以下方式定义索引才能使它与rake db:mongoid:create_indexes一起正常工作:

index(
  { loc: Mongo::GEO2D },
  { background: true }
)

7
实际上,对于 Mongoid 3.0.0 版本,这个方法对我无效。文档中指明了使用以下格式 index({ loc: "2d" }, { min: -200, max: 200 })。干杯。 - rjgonzo

1

所有这些答案都已经过时了,最新版本的MongoDB会抛出一些未初始化的常量Mongo::GEO2D

对于mongoid 4/5,如果您需要处理二维对象或坐标,请查看mongoid-geospatial gem


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接