【问题标题】:Adding proximity filter to user search向用户搜索添加邻近过滤器
【发布时间】:2015-06-20 22:52:24
【问题描述】:

我们在我们的应用程序上设置了用户搜索,到目前为止,它只是基于文本内容查询。

这就是我所拥有的:

在模型/user.rb 中

def self.search(query)
  where("description ilike ?", "%#{query}%")
end

在 app/controllers/users_controller.rb 中

class UsersController < ApplicationController
  before_action :authorized?
  def index
    @users = User.all
    if params[:search]
      @users = User.search(params[:search]).order("created_at DESC")
    else
      @users = User.all.order('created_at DESC')
    end
  end

在视图/index.html.erb 中

<%= form_tag(users_path, :method => "get", id: "search-form") do %>
  <%= text_field_tag :search, params[:search], placeholder: "Search Users" %>
  <%= submit_tag "Search", :name => nil %>
<% end %>

我们正在使用 rails 和 postgres。地理编码器 gem 已安装。我们将当前的纬度和经度存储在单独的列中。

如何添加邻近搜索过滤器,以及在 MVC 方面我将采取哪些步骤?

位置正在像这样存储在我们的方案中

 create_table "users", force: :cascade do |t|
    t.float    "latitude"
    t.float    "longitude"

【问题讨论】:

    标签: ruby-on-rails ruby postgresql proximity rails-geocoder


    【解决方案1】:

    是的,地理编码器主页没有太多信息。我在实际的 README 中找到了更多详细信息:

    https://github.com/alexreisner/geocoder#readme

    如果您想按邮政编码搜索,您需要在表单中添加一个文本字段输入 - 我们称之为zip_code。如果您想要一个可变距离,还可以添加一个选择标签,其中包含表示距离(以英里为单位)的数值,调用此字段distance

    然后在服务器端你需要将 zip 转换为经纬度。

    zip_result = Geocoder.search(params[:zip_code])
    # Is an array of results, take the first one
    if zip_result 
      result = zip_result.first
      lat = result.latitude
      lon = result.longitude
    
      # now we can search with our model: we are asking
      # Show me all Users within "distance_in_miles" of this geocoded
      # zip code
      distance_in_miles = params[:distance].to_i
      User.search(params[:query]).near([lat, lon], distance_in_miles)
    end
    

    这没有任何错误检查或验证 - 它基本上是一个概念证明。

    【讨论】:

    • 我在文档中找不到任何关于向邻近搜索添加过滤器的具体内容。
    • 我可以将它添加到上面的索引方法中吗?
    • 我编辑了我的问题以显示如何存储纬度和经度。我相信它可以通过模型访问。我想我应该使用 User.search(params[:query]).near([latitude, longitude], distance_in_miles) 添加到上面的方法(如果我错了,请纠正我)但是我想知道如何获取用户输入的接近度。我不希望它是后端控制的静态数字,而是用户可以从视图中控制的东西。
    • @user3576650 我回答了你关于接近度的问题。您显示一个带有各种选项的 SELECT 菜单,对用户 zip 进行地理编码,然后询问您是否可以询问您的模型:“显示此 zip X 英里内的所有用户”
    • 我没有使用邮政编码,我有具体的坐标。
    【解决方案2】:

    知道了。我将用户控制器上的索引功能修改为

    if params[:search]
      @users = User.search(params[:search]) \
        .near([current_user.latitude, current_user.longitude], 10) \
        .order("created_at DESC")
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-11-15
      • 2019-11-11
      • 2019-08-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多