我正在开发一个项目,我必须使用postgresql数据库实现自由文本,我无法通过使用@@而不是like命令来理解它是如何工作的。
我有一张桌子
Employee
- Id
- Name
- Location
- ManagerName
//my query was
select * from Employee where name @@ 'xxx'
我正在搜索名称作为自由文本,它会给出结果,可以告诉我索引或搜索目录在哪里,因为我没有制作和配置等但它仍在工作。
postgresql是否有机会为所有表执行此操作或在运行时创建目录?
任何人都能告诉我它是如何运作的吗?
答案 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
a
和b
都是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}}运营商做了什么。)