1

我有三个模型,故事,帖子和标签。Story 与 Post 是一对多的关系,与 Tag 是多对多的关系。

我使用以下范围来搜索至少有一个标签与一组标签匹配的故事:

scope :in_tags, lambda {|category_array, tag_array|
                            Story.joins('LEFT OUTER JOIN stories_tags ON stories_tags.story_id  = stories.id').
                                  joins('LEFT OUTER JOIN tags ON tags.id = stories_tags.tag_id').
                                  where("tags.name in (:tag_array)", :tag_array => tag_array ).
                                  group("stories.id")
  }

请注意,我使用 GROUP_BY 以便如果该故事具有多个匹配标签,则范围不会多次返回该故事。

我使用以下 pg_search_scope 搜索具有指定文本的故事或帖子:

  pg_search_scope   :with_text, 
                    :against => :title, 
                    :using => { :tsearch => { :dictionary => "english" }},
                    :associated_against => { :posts => :contents }

这两个范围都可以彼此独立地正常工作。但是,当我尝试将它们链接在一起时,我遇到了 postgreSQL 错误:

    ActiveRecord::StatementInvalid (PG::Error: ERROR:  column "pg_search_79dd68cf7f962ac568b3d7.pg_search_c5f43d73058486e1799d26" must appear in the GROUP BY clause or be used in an aggregate function
LINE 1: ...e"::text, '')) || to_tsvector('english', coalesce(pg_search_...
                                                             ^
: SELECT  "stories".*, ((ts_rank((to_tsvector('english', coalesce("stories"."title"::text, '')) || to_tsvector('english', coalesce(pg_search_79dd68cf7f962ac568b3d7.pg_search_c5f43d73058486e1799d26::text, ''))), (to_tsquery('english', ''' ' || 'track' || ' ''')), 0))) AS pg_search_rank FROM "stories" LEFT OUTER JOIN stories_tags ON stories_tags.story_id  = stories.id LEFT OUTER JOIN tags ON tags.id = stories_tags.tag_id LEFT OUTER JOIN (SELECT "stories"."id" AS id, string_agg("posts"."contents"::text, ' ') AS pg_search_c5f43d73058486e1799d26 FROM "stories" INNER JOIN "posts" ON "posts"."story_id" = "stories"."id" GROUP BY "stories"."id") pg_search_79dd68cf7f962ac568b3d7 ON pg_search_79dd68cf7f962ac568b3d7.id = "stories"."id" WHERE  (tags.name in (sports') AND (((to_tsvector('english', coalesce("stories"."title"::text, '')) || to_tsvector('english', coalesce(pg_search_79dd68cf7f962ac568b3d7.pg_search_c5f43d73058486e1799d26::text, ''))) @@ (to_tsquery('english', ''' ' || 'track' || ' ''')))) GROUP BY stories.id ORDER BY latest_post_id DESC LIMIT 5000 OFFSET 0):

有没有办法将 pg_search 与需要带有 GROUP_BY 子句的连接表的范围一起使用?

4

1 回答 1

0

我最终不得不从.group()方法(我似乎无法使用 pg_search)切换到select("DISTINCT(stories.id), stories.*). 我也利用ActiveRecords#preloadso 急切地加载相关的标签记录

于 2013-05-29T16:08:25.107 回答