PostgreSQL 分组错误:有时仅在表存在时才通过该表进行分组

4

这是一个奇怪的问题。我正在使用PG搜索以及一些自制类来填充站点上的搜索结果。自制类是用来进一步细化搜索结果的标签。例如,您搜索食物并且想要有机食品,因此您通过没有被标记为有机食品和食物的标签来减少搜索结果。它相当长时间都运作良好。

所有这一切始于我升级到4.2.1版本的rails之后。

我已经能够将错误追踪到特定的代码行:

 joins(:tags).where(tags: {id: tag_list }).group("businesses.id").having("count(*) 
 = #{tag_list.size}")

这行代码是以下函数的一部分:

  def self.tagged_with_all(tag_list)
   unless tag_list.empty?
     joins(:tags).where(tags: {id: tag_list }).group("businesses.id").having("count(*) = #{tag_list.size}")
  else
   all
  end
 end

错误看起来像这样:

PG::GroupingError: ERROR:  column "pg_search_businesses.rank" must 
appear in the GROUP BY clause or be used in an aggregate function
LINE 1: ...UP BY businesses.id HAVING count(*) = 1  ORDER BY pg_search_...

所以我想为什么不遵循错误的建议,将pg_search_business.rank添加到聚合中,这样上面的麻烦行就变成了:

 joins(:tags).where(tags: {id: tag_list }).group("businesses.id", 
 "pg_search_business.rank").having("count(*) 
 = #{tag_list.size}")

这段代码有时可以工作,但在调用此函数时,pg_search_business.rank并不总是存在。对于这些情况,如果我使用上面直接的代码,就会产生以下错误:

PG::UndefinedTable: ERROR:  missing FROM-clause entry for table 
"pg_search_businesses"LINE 1: ...."name" = 'Kid Friendly') 
GROUP BY businesses.id, pg_search_

我现在想知道是否有一种可靠的方法来检查pg_search_business.rank在函数范围内是否存在,或者是否有更好的RoR方法来处理这个特定问题。

当方法self.tagged_with_all在pg_search的范围之外被调用时,就会出现错误。

我正在面临两个不同的分组问题,一个是我们必须使用pg_search_businesses.rank进行分组,另一个则不需要。我正在寻求解决这个问题的最佳方法。

非常感谢您的帮助。我是Ruby编程的新手,这是我的第一个与Ruby相关的问题,如果需要更多信息,请告诉我。


有时候在使用 PG Search 时,您会使用 tagged_with_all 范围,有时候则是用于其他目的? - mu is too short
我基本上已经在做这个了,当使用pg_search时它能很好地工作,但是当我在没有使用pg_search的情况下调用此方法时,我会得到这个错误PG :: UndefinedTable:ERROR:找不到表“pg_search_businesses”的FROM子句条目 LINE 1:...“name” ='Kid Friendly')GROUP BY businesses.id,pg_search_ - FujiRoyale
但是您需要在作用域内调用 group 一次,然后再在作用域外调用一次,不是吗? - mu is too short
我不确定我理解了。你能详细说明一下吗? - FujiRoyale
1
当您使用pg_search时,您会说x.tagged_with_all(...).group("pg_search_business.rank"),否则您只需使用x.tagged_with_all(...),并且在范围内不会提到pg_search_business.rank - mu is too short
显示剩余4条评论
1个回答

0

感谢 @mu is too short

问题被追踪到添加了一个变量,该变量在有问题的函数范围之外设置。目前,这是跟踪何时需要在分组中使用 pg_search_businesses.rank 的唯一方法。

我添加了以下逻辑来设置全局变量 $group_text

    unless q.empty?
     $group_text = "businesses.id" + "," + " pg_search_businesses.rank"
    else
     $group_text = "businesses.id"
    end

这是我添加代码的函数(这样你就可以知道 q 是什么以及它来自哪里)。

  def self.search(q)
    unless q.empty?
     $group_text = "businesses.id" + "," + " pg_search_businesses.rank"
    else
     $group_text = "businesses.id"
    end
    unless q.empty?
      search_text(q)
    else
      all
    end
  end

这似乎是一个解决方案,但我仍然开放接受其他解决此特定问题的方法,因为这个方法感觉有点不太正规。

再次感谢 SO 和 mu is too short。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接