【问题标题】:PHP MYSQL search based on rating and timestamp基于评级和时间戳的 PHP MYSQL 搜索
【发布时间】:2013-03-26 09:38:13
【问题描述】:

我的搜索查询运行如下:

 select * from posts p where p.post like '%test%' ORDER BY p.upvotes DESC, 
 p.unix_timestamp DESC LIMIT 20

如果搜索关键字的结果超过 20 个,我会找出最小时间戳值,将其存储在隐藏元素中并运行另一个查询以加载更多结果,例如:

select * from posts p where p.post like '%test%' and p.unix_timestamp < 1360662045
ORDER BY p.upvotes DESC, p.unix_timestamp DESC LIMIT 20

真正发生的事情是我的第一个查询忽略了(显然,我的错误)由于我的ORDER BY p.upvotes DESC 而没有任何投票(意思是 0 票)的帖子,因此,我注意到它获取了表中的第一个帖子在前 20 个结果中,因此最小时间戳成为第一个帖子的时间戳。现在,在此之后,如果我尝试获取小于最小时间戳的下 20 个结果,它不会给出任何结果。

现在,我只是使用 upvotes 排序来获取最高记录。我应该使用像贝叶斯平均值这样的算法还是其他算法?

如果我不得不继续使用当前的订购系统,或者我应该使用任何可行且更有效的方法,请告知我如何改进查询?

附:如果可能,请参考一些关于贝叶斯平均值的资源(它似乎是最常用的)或其他替代方法?

【问题讨论】:

  • 您的第一个查询不应忽略点赞数为 0 的帖子,而是开始显示所有帖子,包括点赞数为 0 的帖子,从点赞数最高的帖子开始。如果所有人都赞成 0,它将按时间戳排序。我错过了什么吗?附言您也应该将达到的 upvotes 值存储在隐藏字段中并将其传递给第二个查询。
  • 您的查询没有任何内容表明它会忽略 0 个赞成票。您提供的查询将显示他们
  • 另外,当您批量检索结果时,对像 UPVOTES 这样的变量列进行排序会导致意外的行为。如果在运行第一批和第二批之间投票数发生变化怎么办?您可能会得到重复或缺失的结果。
  • 如果两个批次之间的投票计数发生变化,这将无济于事。
  • 它忽略那些零票的唯一方法是如果有 20 个或更多匹配的记录超过零票。另请注意,在 LIKE 中使用前导通配符意味着它会忽略索引并且会很慢。

标签: php mysql sql-order-by rating-system


【解决方案1】:

在您第一次进行搜索时存储时间戳,然后将其用于下一个查询,您可以使用以下内容:-

$sql = "SELECT * 
FROM posts p 
LEFT OUTER JOIN (SELECT post_id, COUNT(*) FROM post_ratings WHERE timestamp_rated <= $SomeTimeStoredBetweenPages GROUP BY post_id) pr ON p.id = pr.post_id 
WHERE p.post like '%test%' 
ORDER BY pr.post_ratings DESC, p.unix_timestamp 
DESC LIMIT ".(($PageNo - 1) * 20)." 20";

这只是一个例子,因为我对你的表结构一无所知。也不确定您是否只是为每个赞成票设置一行,或者是否还有反对票要考虑在内。

【讨论】:

  • 反对票也有,赞成票和反对票都有特定的行。表结构与您建议的完全一样。
  • 我想你假设我正在做分页这就是变量$pageNo 的原因,但我只是在最后给出一个链接以加载更多结果。那么我怎样才能将您的查询放入我的结构中呢?
  • 您可以在子选择中添加一个检查该行是赞成票还是反对票作为 WHERE 子句。通过提供“更多记录”的链接,您实际上是在进行分页。只需在该链接的末尾添加一个变量作为页码(默认为 1)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-10-18
  • 2011-05-10
  • 1970-01-01
  • 2011-06-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多