2

我有一个搜索功能,它基本上运行模型记录的有序列表。问题是每当我打电话.search.limit(5)时,结果的顺序与我打电话时的顺序不同.search

这是我的一些方法

    def self.search(server_name, pvp_type)
          if server_name.nil?
            result = Rom::Leaderboard.order('pvp_vs desc, win_percent desc').limit(200) 
          end
    end

当我打电话

Rom::Leaderboard.search(nil, 2).pluck(:actor_name)

SQL翻译:

SELECT "rom_leaderboards"."actor_name" FROM "rom_leaderboards" WHERE "rom_leaderboards"."pvp_type" = 2 ORDER BY pvp_vs desc, win_percent desc LIMIT 200

我得到以下结果:

[Zarglon, Lirav, adf, sdfa, Nonad, ...]

Zarglon 和 Lirav 具有相同的pvp_vs&win_percent属性值;afd、sdfa 和 Nonad 也有同样的关系。

现在当我打电话

Rom::Leaderboard.search(nil, 2).limit(5).pluck(:actor_name)

SQL翻译:

SELECT "rom_leaderboards"."actor_name" FROM "rom_leaderboards" WHERE "rom_leaderboards"."pvp_type" = 2 ORDER BY pvp_vs desc, win_percent desc LIMIT 5

我得到以下结果:

[Lirav, Zarglon, sfda, Nonad, adf]

这些查询都是正确的(因为搜索返回一个基于的有序列表pvp_vs & win_percent并且两个列表都正确排序)。但我希望它们是一样的。由于某种原因,限制改变了这个顺序。有没有办法让它们保持不变?

4

1 回答 1

4

假设您尝试按第一个元素对该数组进行排序:

[
  [ 1, 1 ],
  [ 1, 2 ],
  [ 1, 3 ]
]

这两个(以及其他几个)都是有效结果,因为您有重复的排序键:

[ [1,1], [1,2], [1,3] ]
[ [1,3], [1,1], [1,2] ]

您在数据库中遇到了同样的问题。你说:

Zarglon 和 Lirav 具有相同的pvp_vs&win_percent属性值;afd、sdfa 和 Nonad 也有同样的关系。

所以这五个值可以以任何顺序出现,并且仍然满足您指定的 ORDER BY 条件。他们甚至不必在同一查询的两次执行中以相同的顺序从数据库中出来。

如果您想要一致的排序,您需要确保结果集中的每一行都有一个唯一的排序键,以便一致地打破平局。这是 ActiveRecord,因此您将拥有一个独特的id可用记录,因此您可以使用它来打破您的订购关系:

result = Rom::Leaderboard.order('pvp_vs desc, win_percent desc, id').limit(200) 
# --------------------------------------------------------------^^

这将为您提供定义明确且独特的排序。

于 2013-10-10T19:50:09.900 回答