私は保持し、Position(lat,lon)
保持するデータベースモデルを持っていますlatitudes
longitudes.
show_close_by
度単位の位置(my_lat, my_lon)
、許容範囲(キロメートル単位)を受け取り、許容範囲内にあるデータベース内の位置のリストを返すコントローラーアクションがあります。
そのために、2つの座標間の距離(地球の表面上)をキロメートルで計算するhaversine_distance式を使用します(lat1, lon1, lat2, lon2)
。
クエリを高速化するために、haversine_distance
数式全体をクエリに記述しました。
... WHERE 2*6371*asin(sqrt( power( sin( (:lat2-latitude)*pi()/(180*2) ) ,2) + cos(latitude*pi()/180)*cos(:lat2*pi()/180)*power(sin( (:lon2-longitude)*pi()/(180*2) ),2) )) < tolerance
クエリの詳細は重要ではありません。私の疑問は、データベース内のすべての位置に対してこの巨大な関数を計算する必要があるかどうかです。より単純な関数を使用して、明らかに遠すぎる位置を除外できますか?
ネストされたSQLクエリを使用すると、大きな「正方形」(緯度/経度空間)内にある位置をデータベースにクエリして、よりコストのかかる三角関数でそれらをフィルタリングできます。次のようなもの:
SELECT * FROM ( SELECT * FROM Positions WHERE lat-latitude < some_reasonable_upper_bound AND lon-longitude < same_upper_bound ) WHERE costly_haversine_distance < tolerance
最後に、私の質問:これをRailsに実装するにはどうすればよいですか(クエリ全体を自分で作成せずに)?Positions.where(reasonable_upper_bound).where(costly_but_accurate_restriction)
ネストされたクエリを作成しますか?そうでない場合、どのように?
どうもありがとう!