SQL用于搜索与acts_as_tsearch的多对多关系

时间:2009-04-23 06:28:09

标签: sql ruby-on-rails full-text-search

我正在使用rails的acts_as_tsearch插件来使用Postgresql进行全文搜索。

他们举了一个多表搜索示例: http://code.google.com/p/acts-as-tsearch/wiki/ActsAsTsearchMethod

但这只是一对多的关系。我试图让它也搜索页面上标签的多对多关系(has_and_belongs_to_many或habtm)。但我的SQL还不够先进。

这是我到目前为止所得到的:

  acts_as_tsearch :vectors => {
    :fields => {
      "a" => {:columns => ["pages.name"], :weight => 1.0},
      "b" => {:columns => ["pages.description"], :weight => 0.2},
      "c" => {:columns => ["tags.name"], :weight => 0.2}
    },
    :tables => {
      :tags => {
        :from => "tags INNER JOIN taggings ON tags.id = taggings.tag_id",
        :where => "((taggings.taggable_type = 'Page') AND (taggings.taggable_id = ???.id) AND ((taggings.context = 'tags')))"
      }
    }
  }

我不确定如何引用页面ID(我把???放在哪里)。

感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

嗯,这背后的SQL将是:

select
    p.name,
    p.description,
    t.name
from
    pages p
    inner join taggings ts on
        p.page_id = ts.taggable_id
        and ts.taggable_type = 'Page'
        and ts.context = 'tags'
    inner join tags t on
        ts.tag_id = t.tag_id

所以,你的Ruby看起来像:

acts_as_tsearch :vectors => {
  :fields => {
    "a" => {:columns => ["p.name"], :weight => 1.0},
    "b" => {:columns => ["p.description"], :weight => 0.2},
    "c" => {:columns => ["t.name"], :weight => 0.2}
  },
  :tables => {
    :tags => {
      :from => "pages p
        inner join taggings ts on
            p.page_id = ts.taggable_id
            and ts.taggable_type = 'Page'
            and ts.context = 'tags'
        inner join tags t on
            ts.tag_id = t.tag_id"
    }
  }
}

这是通过多对多表的标准方法 - 只需从一个表开始,加入映射,然后加入另一个表。瞧!多对多的结果!