【问题标题】:Activerecord sort OR query by best matchActiverecord 按最佳匹配排序 OR 查询
【发布时间】:2025-11-26 15:45:01
【问题描述】:

我有一个带有first_namelast_name 属性的用户模型。我想编写一个 api,可以通过first_namelast_name 或两者来搜索用户。

问题是当用户同时使用first_namelast_name 进行搜索时。我想对结果进行排序,以便完全匹配的记录位于顶部。同时匹配first_namelast_name 的记录应该先跟部分匹配的记录。

这是我当前的查询:

q.where('first_name like ? or last_name like ?', "%#{first_name}%", "%#{last_name}%")

【问题讨论】:

    标签: ruby-on-rails postgresql ruby-on-rails-4 activerecord


    【解决方案1】:

    不是 SQL 方面的专家,所以可能有更好的方法,但可以使用这些数据

    User.create([
      { first_name: "Random", last_name: "Last" },
      { first_name: "Random", last_name: "Random" },
      { first_name: "First", last_name: "Random" },
      { first_name: "First", last_name: "Last" },
      { first_name: "Not First", last_name: "Last" },
      { first_name: "First", last_name: "Not Last" },
      { first_name: "Not First", last_name: "Not Last" }
    ])
    

    当我得到(没有排序)

    User.where("first_name like ? or last_name like ?", "%First%", "%Last%").collect { |u| [u.first_name, u.last_name] }
    # User Load (0.2ms)  SELECT "users".* FROM "users" WHERE (first_name like '%First%' or last_name like '%Last%')
    => [["Random", "Last"], ["First", "Random"], ["First", "Last"], ["Not First", "Last"], ["First", "Not Last"], ["Not First", "Not Last"]]
    

    然后如果我添加 .order(User.send(:sanitize_sql, ["first_name like ? and last_name like ? DESC, first_name like ? OR last_name like ? DESC", "%First%", "%Last%", "%First%", "%Last%"]) 我得到

    User.where("first_name like ? or last_name like ?", "%First%", "%Last%").order(User.send(:sanitize_sql, ["first_name like ? and last_name like ? DESC, first_name like ? OR last_name like ? DESC", "%First%", "%Last%", "%First%", "%Last%"])).collect { |u| [u.first_name, u.last_name] } 
    # User Load (0.2ms)  SELECT "users".* FROM "users" WHERE (first_name like '%First%' or last_name like '%Last%') ORDER BY first_name like '%First%' and last_name like '%Last%' DESC, first_name like '%First%' OR last_name like '%Last%' DESC
    => [["First", "Last"], ["Not First", "Last"], ["First", "Not Last"], ["Not First", "Not Last"], ["Random", "Last"], ["First", "Random"]]
    

    在这些事情上更加专家的人可能知道更好的方法,但这看起来正在完成。

    【讨论】: