在PostgreSQL中使用相关表进行全文搜索

时间:2013-02-24 15:44:13

标签: postgresql search full-text-search search-engine postgresql-9.1

任务: 在PostgreSQL中的多个表中实现全文搜索。

例如,一个项目表 - 项目: 需要搜索的字段有两个:标题和说明。 在此表上创建索引:

ALTER TABLE public.projects ADD COLUMN search_fts tsvector;
UPDATE public.projects SET search_fts =
to_tsvector(
    coalesce(title, '') ||' '||
    coalesce(description, '') || ' '
);
CREATE INDEX in_projects_idx ON public.projects
  USING gin (search_fts);

现在搜索很简单:

SELECT
    DISTINCT p.id,
    p.title,
    ts_rank(
        p.search_fts,
        to_tsquery('word1 | word2')
    ) as rank
FROM
    projects p
WHERE
    p.search_fts @@ to_tsquery('word1 | word2')
ORDER BY rank DESC;

掺和。现在我们需要查看表和项目类别 - project_categories。 类似于创建tsvector和字段名称上的表。 现在搜索查询是:

SELECT
    DISTINCT p.id,
    p.title,
    category.name as categoryName,
    ts_rank(
        (
            coalesce(p.search_fts, '') ||' '||
            coalesce(category.search_fts, '')
        ),
        to_tsquery('word1 | word2 | categoryName')
    ) as rank
FROM
    projects p
LEFT JOIN project_categories category
    ON p.category_id = category.category_id
WHERE
    (
        coalesce(p.search_fts, '') ||' '||
        coalesce(category.search_fts, '')
    ) @@ to_tsquery('word1 | word2 | categoryName')
ORDER BY rank DESC;

更加成熟。现在,搜索必须处理与项目相关的数十个表,如一对多和多对多。

数字加入正在增长。结合越来越多的领域。

其实这个问题我正确的方式?你会如何解决这个问题?

我也考虑带有视图的版本。 例如,建立在这样的请求上:

(
  SELECT 
      p.id as project_id,
      p.search_fts
  FROM projects p
) UNION ALL (
  SELECT 
      p.id as project_id,
      category.search_fts
  FROM projects p
  JOIN project_categories category
      ON p.category_id = category.category_id
)

最后,我们获得整体指数。通过它搜索。 但在视图中必须结合十几个请求进行各种通信选项。 对您对此选项的看法感兴趣。

抱歉我的英文。

1 个答案:

答案 0 :(得分:3)

您有几个选择:

  • 在所有输入表上使用触发器来维护一个汇总表,该表汇总了文本行中感兴趣的所有记录。对于包含1个或多个customer和一个或多个phone条目的address等简单案例,这可以正常运行,您可以将其作为{{1}放在摘要搜索表中在连接表上使用简单连接和|customername|customerid|phone1|phone2|phone3|...|address1|address2|...。但是,它很难扩展到深层嵌套的关系,并且可能会产生一些锁定和并发问题。

  • 使用像Apache Solr这样的外部搜索系统来解决复杂的搜索问题。