SQL搜索与acts_as_tsearch的多对多关系

SQL搜索与acts_as_tsearch的多对多关系,sql,ruby-on-rails,full-text-search,Sql,Ruby On Rails,Full Text Search,我正在使用用于rails的acts_as_tsearch插件使用Postgresql进行全文搜索 此处给出了多表搜索的示例: 但这只是一对多的关系。我试图让它也在页面上搜索多对多关系(has_和_属于_-to_-many或habtm)中的标签。但是我的SQL不够高级 以下是我到目前为止得到的信息: acts_as_tsearch :vectors => { :fields => { "a" => {:columns => ["pages.name

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

此处给出了多表搜索的示例:

但这只是一对多的关系。我试图让它也在页面上搜索多对多关系(has_和_属于_-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(我把它放在哪里?)


谢谢你的帮助

这背后的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"
    }
  }
}

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

这背后的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"
    }
  }
}

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

你能解释一下标签id的用途吗?好问题,对不起,我应该解释一下。它是多态的,所以taggable_id指的是任何可以有标记的模型。在这种情况下,它可以称为page_id,因为只有我的页面有标记,但它们使它具有多态性,因此任何模型都可以有标记。基本上,“taggings”表保存页面和标记的ID,以连接多对多关系。谢谢你的帮助!你能解释一下标签id的用途吗?好问题,对不起,我应该解释一下。它是多态的,所以taggable_id指的是任何可以有标记的模型。在这种情况下,它可以称为page_id,因为只有我的页面有标记,但它们使它具有多态性,因此任何模型都可以有标记。基本上,“taggings”表保存页面和标记的ID,以连接多对多关系。谢谢你的帮助!