1

我在带有 postgresql 的 Rails 上有一个非常简单的标签模型:

class Tag < ActiveRecord::Base
  has_many :taggings
  has_many :posts, :through => :taggings, 
                   :source => :tagged, :source_type => 'Post'
end

class Tagging < ActiveRecord::Base
  belongs_to :tag 
  belongs_to :tagged, :polymorphic   => true  
end

class Post < ActiveRecord::Base
  has_many :taggings, :as => :tagged
  has_many :tags, :through => :taggings 
end

有没有一种简单的方法可以找到所有具有 2 个以上指定标签的帖子?例如,假设有“style”、“men”、“women”、“sale”标签。我想创建一个接受标签数组的通用 find 语句。因此,如果输入是 ["style"] 那么它应该返回所有带有该标签的帖子(简单)或者如果输入是 ["style", "men"] 那么它应该返回所有带有标签 "style" AND "的帖子男人”。

4

2 回答 2

1

有没有一种简单的方法可以找到所有具有 2 个以上指定标签的帖子?例如,假设有“style”、“men”、“women”、“sale”标签

经典的方法是使用数据透视表:posts <-> posts_tags <-> tags

不过,您可以像这样对标签进行编码,因为这是最简单的方法(保持完整性、外键、为您提供易于扫描的标签列表等)。

这种方式对于少量帖子和少量标签具有不错的性能,但查询起来很麻烦(您需要一些聚合、INTERSECT 或每个标签 1 个 JOIN)并且如果标签不是很有选择性的话,速度会非常慢。

显然,对于您想要执行的搜索,这很糟糕。所以你有两个选择:

1- 在您的帖子表中的 INTEGER[] 列中具体化帖子的标签 ID 列表,在其上放置一个 gist(或 gin)索引,并使用“包含整数数组”运算符,该运算符被索引,非常快,而且查询起来很简单。

2-只需将您的标签作为文本并在其上添加全文索引

两者都非常快,具有整数数组的优势。

于 2011-07-23T14:22:14.827 回答
0

我可以在这里写一个非常糟糕的 SQL,什么会做 JOINS 和 GROUP BY,但这是 rails,所以你可以做得更好,首先你的 Post 模型应该这样定义:

class Post < ActiveRecord::Base
  has_many :taggings, :as => :tagged, :couter_cache => true
  has_many :tags, :through => :taggings 
end

您需要迁移才能将taggings_count列添加到您的帖子表中:

add_column :posts, :taggings_count, :integer, :default => 0
add_index :posts, :taggings_count

并且每当为 Post 创建 Tagging 时,它都会增加 taggings_count 值,您可以在查询中使用它来有效地查找具有两个或多个标签的帖子:

Post.all( :conditions => [ 'taggings_count >= ?' 2] )
于 2011-07-23T03:26:34.000 回答