postgresql中的自由文本搜索如何工作

时间:2014-04-22 10:12:40

标签: postgresql full-text-search

我正在开发一个项目,我必须使用postgresql数据库实现自由文本,我无法通过使用@@而不是like命令来理解它是如何工作的。

我有一张桌子

Employee
- Id
- Name
- Location
- ManagerName

//my query was

select * from Employee where name @@ 'xxx'

我正在搜索名称作为自由文本,它会给出结果,可以告诉我索引或搜索目录在哪里,因为我没有制作和配置等但它仍在工作。

postgresql是否有机会为所有表执行此操作或在运行时创建目录?

任何人都能告诉我它是如何运作的吗?

1 个答案:

答案 0 :(得分:1)

实际发生了什么

如果查看为@@定义的运算符,您会看到有一些变体具有不同的数据类型。对于同一个运营商,它们都是重载

regress=> \do @@
                                        List of operators
   Schema   | Name | Left arg type | Right arg type | Result type |         Description          
------------+------+---------------+----------------+-------------+------------------------------
 pg_catalog | @@   | text          | text           | boolean     | text search match
 pg_catalog | @@   | text          | tsquery        | boolean     | text search match
 pg_catalog | @@   | tsquery       | tsvector       | boolean     | text search match
 pg_catalog | @@   | tsvector      | tsquery        | boolean     | text search match

现在,如果你a @@ b ab都是text字段(或varchar,它们会被转换为文本),那么它会调用@@(text, text) to_tsvector(a) @@ to_tsquery(b)运营商。

自动将输入转换为文本搜索令牌列表,然后进行比较。

所以它基本上是regress=> SELECT 'frightening' @@ 'frightened'; t (1 row) 的简写。这就是它起作用的原因。

请参阅全文搜索有两个部分:使用tsearch向量的比较操作和执行所有奇特通配符和词干分析的查询,以及索引支持。

您在这里使用的是比较部分,但不是索引。索引可以使更快,但不会添加功能

一步一步

所以这仍然有效:

@@(tsvector,tsquery)

因为它实际上基本上是使用regress=> SELECT to_tsvector('frightening') @@ to_tsquery('frightened'); t (1 row) 运算符转换双方,例如:

regress=> SHOW default_text_search_config;
 default_text_search_config 
----------------------------
 pg_catalog.english
(1 row)

它使用全局配置的tsearch词干词典,在我的系统上是:

regress=> SELECT to_tsvector('english', 'frightening') @@ to_tsquery('english', 'frightened');
 t
(1 row)

所以它确实在做:

regress=> SELECT to_tsvector('english', 'frightening'), to_tsquery('english', 'frightened');
 to_tsvector  | to_tsquery 
--------------+------------
 'frighten':1 | 'frighten'

让我们分别看看每一方:

正在比较:

@@

看看它做了什么?根据英语规则,用词语将它们修剪成根或茎。这就是他们匹配的原因。

实际上,具有文本值的explain analyze运算符只是简写。在你的情况下, 没有索引,因为不需要索引,但有一个可能会让事情变得更快。如果您@@查询,您会发现它仍然只是做一个普通的旧seqscan。

希望这能帮助您了解正在发生的事情。我不确定 - 我依赖于对数据类型和操作符重载等概念的理解,这些概念可能对您来说很熟悉,也可能不熟悉,我故意跳过一些需要解释的内容,这些内容会让您感到困惑(比如如何确切地告诉不同的{{1}}运营商做了什么。)