Postgres全文搜索:如何在多个字段中搜索多个单词?

sma*_*use 5 sql postgresql indexing search full-text-search

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

CREATE TABLE shop (
  id SERIAL PRIMARY KEY,
  name TEXT NOT NULL,
  description TEXT,
  address TEXT NOT NULL,
  city TEXT NOT NULL
);
Run Code Online (Sandbox Code Playgroud)

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

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));
Run Code Online (Sandbox Code Playgroud)

现在,如果我想在每个索引中搜索一个词,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')
Run Code Online (Sandbox Code Playgroud)

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

SELECT * FROM shop WHERE MATCH(name, description, address, city) AGAINST('$word')
Run Code Online (Sandbox Code Playgroud)

Postgresql 的解决方案是什么?

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

Den*_*ret 11

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

您可以构建一个查询来执行此操作

... where to_tsvector('italian', name||' '||coalesce(decription,'')...) @@ to_tsquery('$word')
Run Code Online (Sandbox Code Playgroud)

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

create index your_index on shop
using GIN(to_tsvector('italian',name||' '||coalesce(decription,'')...))
Run Code Online (Sandbox Code Playgroud)

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

  • 对于多词搜索,使用带有运算符“&”、“|”和“!”的“to_tsquery”语法:“to_tsquery('molto & facile')”。更多细节在这里:http://www.postgresql.org/docs/9.2/static/textsearch-intro.html (3认同)