我想用思考狮身人面像进行复杂的搜索:
搜索以下用户: - >住在城市(city_id属性) - >或者有能力搬到城市(mobile_cities association) - >或者距离纬度/经度点的最大距离,每个用户的最大距离不同,并在mobility_distance属性中设置。
现在我用3个不同的搜索做了,我volontary设置了一个很大的per_page数,然后我将3个结果合并到一个数组上,然后分页这个数组:
#users living in the @city
search_set_living = search_set.merge({:city_id => @city.id })
users_living = User.search :with => search_set_living.dup,
:page => 1, :per_page => 1000
#users declaring hability to move to the @city
search_set_mobile = search_set.merge({:mobile_cities_ids => @city.id })
users_mobile = User.search :with => search_set_mobile.dup, :page => 1, :per_page => 1000
#users living at a maximum distance from the origin point(custom distance for each user, max 30km)
search_set_around = search_set.merge({"@geodist" => 0.0..30_000.0})
users_around = User.search :geo => [@search_latitude * Math::PI / 180 , @search_longitude * Math::PI / 180],
:with => search_set_around.dup,
:page => 1, :per_page => 1000
users_around_filtered = users_around.dup.delete_if{|user| (user.mobility_distance * 1000 )< user.sphinx_attributes['@geodist'] }
#merge the 3 results in a array
all_users = (users_mobile.flatten + users_around_filtered.flatten).uniq
#look for facets and paginate the array
@facets = User.facets :with => {:user_id => all_users.map(&:id)}
@users_to_display = all_users.paginate(:page => params[:page], :per_page => 10)
这很好但我不满意: 性能不太好, - 我想要能够对这样的多个属性进行排序:order =&gt; “created_at DESC,@ relance DESC”
我希望在单个sphinx的搜索中进行完全相同的搜索。 我知道我应该使用"OR Logic with Attribute Filters" from the docs,但我不知道如何将它与geo_search调用混合... 我真的不知道该怎么做, 你能帮助我吗?
非常感谢,
答案 0 :(得分:3)
正如您猜测的那样,:sphinx_select
选项绝对是您的朋友。让我们一点一点地把它拼凑起来:
logic = [
"city_id = #{@city.id}",
"IN(mobile_cities_ids, #{@city.id}",
"GEODIST(lat, lng, #{lat}, #{lng}) < (mobility_distance * 1000)"
]
User.search :sphinx_select => "*, #{logic.join(" OR ")}) AS valid",
:with => {:valid => true}
根据需要添加分页,根据需要调整属性名称(也许你的lat / lng属性被命名为其他名称)。我不认为您需要围绕该自定义属性进行IF
调用,就像在文档中一样,但如果事情不适用,可能会给它一个机会。在一个方面也应该很好。
答案 1 :(得分:-1)
太棒了!非常感谢。我只需要纠正一点你的语法(缺少一些括号),以使其工作。 我不得不添加per_page和页面参数,不知道为什么。
logic = ["city_id = #{@city.id}",
"IN(mobile_cities_ids, #{@city.id})",
"GEODIST(latitude, longitude, #{@search_latitude * Math::PI / 180}, #{@search_longitude * Math::PI / 180}) < (mobility_distance * 1000)"]
search_set_logic = search_set.merge({:valid => true})
@users_to_display = User.search :sphinx_select => "*, (#{logic.join(" OR ")}) AS valid",
:with => search_set_logic.dup,
:sort_mode => :extended,
:order => "visibility DESC, last_login_at DESC",
:page => params[:page], :per_page => 10