我有一个Rails 3应用程序,它有一个带名称的模型和一个地理位置(lat / lng)。我将如何在模型中搜索可能的重复项。我想创建一个cron作业或某些东西,检查两个对象是否具有相似的名称,并且彼此相距不到0.5英里。如果这匹配,那么我们将标记对象或其他东西。
我在我的申请中使用Ruby Geocoder和ThinkingSphinx。
答案 0 :(得分:1)
Levenshtein与判断两个文本字符串(即名称)的相似性一样好。
我建议的是(以及或代替单个“lat; long”字符串)单独存储纬度和经度。然后你可以做一个SQL查询来查找一定距离内的其他记录,然后在他们的名字上运行levenshtein。你想尝试尽可能少地运行lev,因为它很慢。
然后你可以做这样的事情:假设你的模特名称是“地方”:
class Place < ActiveRecord::Base
def nearby_places
range = 0.005; #adjust this to get the proximity you want
#lat and long are fields to hold the latitude and longitude as floats
Place.find(:all, :conditions => ["id <> ? and lat > ? and lat < ? and long > ? and long < ?", self.id, self.lat - range, self.lat + range, self.long - range, self.long + range])
end
def similars
self.nearby_places.select do |place|
#levenshtein logic here - return true if self.name and place.name are similar according to your criteria
end
end
end
我已将范围设定为0.005,但我不知道1/2英里应该是多少。让我们解决这个问题:google说一度纬度是69.13英里,所以我猜半英里的度数是1 /(69.13 * 2),它给出了0.0072,所以不错的猜测:)
请注意,我的搜索逻辑会返回一个方形内的任何位置,每个方位一英里,我们当前位于中心位置。这可能包括更多的地方,而不是一个半径为1/2英里的圆圈,我们目前的位置在中心,但它可能是一个快速的方式来获得一些附近的地方。