Tôi có một mô hình cơ sở dữ liệu Position(lat,lon)
nắm giữ latitudes
và longitudes.
Rails Nested SQL Queries
Tôi có một hành động điều khiển được gọi là show_close_by
mà recieves một vị trí trong độ (my_lat, my_lon)
, dung sai (bằng km) và sẽ trả về danh sách các vị trí trong cơ sở dữ liệu nằm trong phạm vi dung sai.
Đối với điều đó, tôi sử dụng công thức haversine_distance tính toán khoảng cách tính bằng kilomet (trên bề mặt trái đất) giữa hai tọa độ (lat1, lon1, lat2, lon2)
.
Để thực hiện các truy vấn nhanh hơn, tôi đã viết toàn bộ haversine_distance
thức trong truy vấn:
... 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
Các chi tiết cụ thể của các truy vấn không thành vấn đề. Nghi ngờ của tôi là: có cần thiết để tính toán hàm rất lớn này cho mọi vị trí trong cơ sở dữ liệu không? Tôi có thể lọc ra một số vị trí rõ ràng quá xa với chức năng đơn giản hơn không? Vâng, tôi có thể: Với một truy vấn SQL lồng nhau, tôi có thể truy vấn cơ sở dữ liệu cho các vị trí nằm trong một "hình vuông" lớn (trong không gian lat/lon), và sau đó lọc chúng với hàm lượng giác tốn kém hơn. Một cái gì đó như sau:
SELECT * FROM (SELECT * FROM Positions WHERE lat-latitude < some_reasonable_upper_bound AND lon-longitude < same_upper_bound) WHERE costly_haversine_distance < tolerance
Cuối cùng, câu hỏi của tôi: làm thế nào tôi có thể thực hiện điều này trong Rails (không phải viết toàn bộ truy vấn)? Positions.where(reasonable_upper_bound).where(costly_but_accurate_restriction)
có tạo một truy vấn lồng nhau không? Nếu không, làm thế nào?
Cảm ơn rất nhiều!
Bạn có biết về [Geocoder] (https://github.com/alexreisner/geocoder) không? Bạn cài đặt gem, thêm một dòng trong mô hình Position của bạn, và sau đó bạn có thể thực hiện các công cụ như 'Position.near ([40.71, 100.23], 20)'. Đá quý này khá phổ biến, vì vậy tôi muốn nói họ làm những gì bạn muốn làm khá tốt. (juts để bạn biết, liên kết 'where' điều khoản không làm những gì bạn muốn. Tôi nghĩ rằng nó chỉ ghi đè lên những cái trước đó). – Robin
Vâng, tôi biết về Geocoder và tôi có thể chỉ cần sử dụng nó, nhưng nó có vẻ hơi lớn đối với những gì tôi muốn (tôi chỉ muốn khoảng cách giữa các đối tượng). Ứng dụng tải một đối tượng Geocoder toàn bộ chậm hơn bao nhiêu so với hàm haversine_distance barebones tôi đã lập trình? – gdiazc
@Robin Nó không ghi đè lên trước đó, nhưng nó * không * phụ thêm các điều kiện bằng cách sử dụng 'AND' cho truy vấn hiện tại, mà không hoàn toàn là những gì người hỏi đang tìm kiếm. – nzifnab