我在一个小型Rails应用上尝试使用Searchkick来执行地理空间搜索,但我无法让它工作。
我有一个Venue模型:
class Venue < ActiveRecord::Base
has_and_belongs_to_many :categories
searchkick locations: ["location"]
def search_data
attributes.merge location: [latitude, longitude]
attributes.merge categories_title: categories.map(&:name)
end
end
我已将数据添加到我的数据库中,我也运行了Venue.reindex。
在我的控制器中,我试图通过运行来搜索:
term = "london"
res = Geocoder.search(term)
@location = res.first.geometry['location'] # lat / lng
@venues = Venue.search '*', where: {
location: {
near: [@location['lat'],@location['lng']],
within: '2km'
}
}
虽然我的数据库中有有效数据,但我总是得到一个空的结果。查看rails控制台,针对elasticsearch执行的查询是:
{
"query":{
"filtered":{
"query":{
"match_all":{
}
},
"filter":{
"and":[
{
"geo_distance":{
"location":[
-0.08077990000000002,
51.5037119
],
"distance":"2km"
}
}
]
}
}
},
"size":1000,
"from":0,
"sort":{
"_geo_distance":{
"location":"51.5037119,-0.08077990000000002"
}
},
"fields":[
]
}
有什么想法吗?
由于
答案 0 :(得分:3)
一些事情:
您是否已将location
映射为geo_point
?如果没有,你可以这样做:
searchkick merge_mappings: true, mappings: {venue: {properties: {locations: {type:"geo_point"}}}}, locations: ["location"]
"distance":"2km"
- 我注意到elasticsearch以距离为单位抛出错误。删除km
可能会对您有所帮助。默认情况下,ES使用km作为距离,因此只需输入没有单位的距离编号
match_all
- 应该有效。我看到你的传递*
这很好,因为ES认为这是一个通配符或“搜索一切”命令。如果您使用来自searchkick的match
查询,则可能需要检查“关键字”参数是否为空,如果是,则传递*
,因为将其保留为空将无效。今天早上有你的问题,我可以在做出这些修改后得到结果
答案 1 :(得分:0)
我们在其中一张桌子上遇到这个问题很长一段时间了。随着Searchkick的最新更新,我们通过使用始终使用散列指定位置的方法解决了它,即{lat:37.12,lon:-121.12},尽可能。使用数组的旧方法很容易在我们的代码和searchkick中按顺序出错,并且使用散列确保正确的值到达应该去的地方。我开始查看searchkick的源代码,并意识到它现在将把哈希处理到所有地方,所以尝试从旧的文档化的数组方法切换到哈希,更新模型,然后重新索引表。