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"] の場合、そのタグを持つすべての投稿を返す必要があります (簡単)。入力が ["style", "men"] の場合は、タグ "style" AND " を持つすべての投稿を返す必要があります。男性」。

4

2 に答える 2

1

指定したタグが 2 つ以上あるすべての投稿を簡単に見つける方法はありますか? 例えば「style」「men」「women」「sale」のタグがあるとします。

古典的な方法は、ピボット テーブルを使用することです: posts <-> posts_tags <-> タグ

ただし、これが最も簡単な方法であるため、このようにタグをエンコードすることもできます (整合性、外部キーを維持し、タグのリストをスキャンしやすくするなど)。

この方法は、少数の投稿と少数のタグに対して適切なパフォーマンスを発揮しますが、クエリが面倒で (タグごとに集計、INTERSECT、または 1 つの JOIN が必要になります)、タグがあまり選択的でない場合は非常に遅くなります。

明らかに、実行したい検索の種類については、これは最悪です。したがって、2 つの選択肢があります。

1- 投稿テーブルの INTEGER[] 列内の投稿のタグ ID のリストを具体化し、その上に要点 (または gin) インデックスを配置し、「整数配列が含まれる」演算子を使用します。これはインデックス付きで、非常に高速です。 、クエリは簡単です。

2-タグをテキストとして配置し、それらに全文インデックスをスローするだけです

どちらも非常に高速で、整数配列に利点があります。

于 2011-07-23T14:22:14.827 に答える
0

JOINS と GROUP BY を行う非常に悪い SQL をここに書くこともできますが、これは Rails であるため、より適切に行うことができます。まず、Post モデルを次のように定義する必要があります。

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

そして、 taggings_count列を posts テーブルに追加するための移行が必要になります。

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

これにより、投稿のタグ付けが作成されるたびに taggings_count の値がインクリメントされ、クエリでそれを使用して、2 つ以上のタグを持つ投稿を効率的に見つけることができます。

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