【问题标题】:Postgres full text search: how to search multiple words in multiple fields?Postgres全文搜索:如何在多个字段中搜索多个单词?
【发布时间】:2015-08-20 04:20:58
【问题描述】:

我第一次使用 Postgresql,我正在尝试在我的网站中创建一个搜索引擎。我有这张桌子:

CREATE TABLE shop (
  id SERIAL PRIMARY KEY,
  name TEXT NOT NULL,
  description TEXT,
  address TEXT NOT NULL,
  city TEXT NOT NULL
);

然后我为表的每个字段创建了一个索引(这是正确的方法吗?或者我可以为所有字段创建一个索引?):

CREATE INDEX shop_name_fts ON shop USING gin(to_tsvector('italian', name));
CREATE INDEX shop_desc_fts ON shop USING gin(to_tsvector('italian', description));
CREATE INDEX shop_addr_fts ON shop USING gin(to_tsvector('italian', address));
CREATE INDEX shop_city_fts ON shop USING gin(to_tsvector('italian', city));

现在,如果我想在每个索引中搜索一个单词,SQL 查询是什么?

我试过了,效果很好:

SELECT id FROM shop WHERE to_tsvector(name) @@ to_tsquery('$word') OR
                          to_tsvector(description) @@ to_tsquery('$word') OR 
                          to_tsvector(address) @@ to_tsquery('$word') OR 
                          to_tsvector(city) @@ to_tsquery('$word')

是否存在更好的方法来做同样的事情? 我可以将to_tsquery 搜索到多个to_tsvector 吗? 我的一个朋友提出了一个解决方案,但它是针对 MySQL 数据库的:

SELECT * FROM shop WHERE MATCH(name, description, address, city) AGAINST('$word')

Postgresql 的解决方案是什么?

另外,我可以将多个to_tsquery 搜索到多个to_tsvector 中吗?如果我想搜索两个词或多个词,SQL 查询是什么?我可以将“两个词”从 PHP 传递给 $word 吗?如果可以,它是如何工作的?它是搜索第一个单词 AND 第二个还是第一个单词 OR 第二个?

【问题讨论】:

  • 您为什么还要对名称或城市进行全文搜索?您可能应该对这些字段进行更简单的比较。
  • 这些是样本数据。我的数据库包含商店数据,名称可以是“The great restaurant”。我要编辑我的问题,抱歉。

标签: sql postgresql search indexing full-text-search


【解决方案1】:

看起来你想要的是,实际上是搜索所有这些字段的串联。

你可以建立一个查询来做这个

... where to_tsvector('italian', name||' '||coalesce(decription,'')...) @@ to_tsquery('$word')

并在完全相同的计算上建立索引:

create index your_index on shop
using GIN(to_tsvector('italian',name||' '||coalesce(decription,'')...))

不要忘记在接受 NULL 值的列上使用 coalesce

【讨论】:

  • 听起来不错,但我得到了这个错误:ERROR: functions in index expression must be marked IMMUTABLE
  • 我解决了这个问题:create index shop_fts on shop using GIN(to_tsvector('italian', name || ' ' || description || ' ' || address || ' ' || city));
  • 那么现在,如何搜索多个单词呢?它是如何工作的?
  • 在索引和 where 部分使用完全相同的措辞。
  • 对于多词搜索,使用to_tsquery的语法和运算符&|!to_tsquery('molto & facile' )。更多细节在这里:postgresql.org/docs/9.2/static/textsearch-intro.html
猜你喜欢
  • 2020-09-11
  • 2013-05-29
  • 1970-01-01
  • 1970-01-01
  • 2020-12-29
  • 1970-01-01
  • 2011-09-14
  • 1970-01-01
  • 2018-01-08
相关资源
最近更新 更多