[英]How do I SQL query for words with punctuation in Postgresql?
如果我有这样的字符串/短语存储在数据库中:
- 什么是Q型操作?
- 程序员指南
- ABC的编码
有没有办法像"Programmers"
或"abc"
或"q-type"
那样传递查询参数,并让它找到"Programmer's"
, "ABC"
和"Q-type"
?
使用tsvector
类型,它是PostgreSQL文本搜索功能的一部分。
postgres> select 'What are Q-type Operations?'::tsvector;
tsvector
-------------------------------------
'Operations?' 'Q-type' 'What' 'are'
(1 row)
您也可以在tsvector上使用熟悉的运算符:
postgres> select 'What are Q-type Operations?'::tsvector
postgres> || 'A.B.C''s of Coding'::tsvector;
?column?
--------------------------------------------------------------
'A.B.C''s' 'Coding' 'Operations?' 'Q-type' 'What' 'are' 'of'
tsvector值是不同词汇的排序列表,这些词汇已被规范化以合并相同单词的不同变体(有关详细信息,请参阅第12章)。 在输入期间自动完成排序和重复消除
如果您还想进行特定于语言的规范化,例如删除常用词('the','a'等)和乘法,请使用to_tsvector
函数。 它还为不同的单词分配权重以进行文本搜索:
postgres> select to_tsvector('english',
postgres> 'What are Q-type Operations? A.B.C''s of Coding');
to_tsvector
--------------------------------------------------------
'a.b.c':7 'code':10 'oper':6 'q':4 'q-type':3 'type':5
(1 row)
显然,对查询中的每一行执行此操作都会很昂贵 - 因此您应该将tsvector存储在单独的列中并使用ts_query()来搜索它。 这也允许您在tsvector上创建GiST索引。
postgres> insert into text (phrase, tsvec)
postgres> values('What are Q-type Operations?',
postgres> to_tsvector('english', 'What are Q-type Operations?'));
INSERT 0 1
使用tsquery和@@运算符进行搜索:
postgres> select phrase from text where tsvec @@ to_tsquery('q-type');
phrase
-----------------------------
What are Q-type Operations?
(1 row)
您可以尝试使用带有TRANSLATE功能的ILIKE,请参见此处 。
例如: translate(field, '.-\\'', '')
这是另一个可能相关的链接。 在将其与搜索字符串进行比较之前,从所有标点符号中删除字段的值。
这听起来像你想要的东西:
http://www.postgresql.org/docs/9.0/static/fuzzystrmatch.html
我不是百分百确定这是否会涵盖你想要的东西。
编辑我不得不在本地运行它来检查(在Windows上使用PostgreSQL 9.0)
这是我发现的:
template1=> select soundex('Programmers'), soundex('Programmer''s');
soundex | soundex
---------+---------
P626 | P626
(1 row)
template1=> select soundex('abc'), soundex('A.B.C.');
soundex | soundex
---------+---------
A120 | A120
(1 row)
template1=> select soundex('Q-type'), soundex('q-type');
soundex | soundex
---------+---------
Q310 | Q310
(1 row)
所以如果你要做soundex(colname) = soundex(<user param>)
应该在where子句中得到你需要的东西。
您需要安装fuzzystrmatch模块:
psql -U <dbowner> -d <database> -f SHAREDIR/contrib/fuzzystrmatch.sql
请参阅有关如何定位SHAREDIR的文档
编辑我刚注意到我忽略了什么,我认为这与ts_vector
功能相结合可能会让你达到目标。
Postgres支持模式匹配,因此您可以在where子句中构建正则表达式http://www.postgresql.org/docs/8.3/static/functions-matching.html
Postgresql通过将文本输入转换为tsvector
类型来支持全文搜索:
steve@steve@[local] =# select input, to_tsvector('english', input)\
from (values('What are Q-type Operations?'),('Programmer''s Guide'),('A.B.C''s of Coding')) x(input);
input | to_tsvector
-----------------------------+------------------------------------
What are Q-type Operations? | 'oper':6 'q':4 'q-type':3 'type':5
Programmer's Guide | 'guid':3 'programm':1
A.B.C's of Coding | 'a.b.c':1 'code':4
(3 rows)
正如您所看到的,默认使用的词干将使“编程”“程序员”和“程序员”完全匹配。
您通常会使用索引的tsvector列或表达式,然后使用@@
运算符将其与tsquery
匹配,例如:
steve@steve@[local] =# select input, to_tsvector('english', input) \
from (values('What are Q-type Operations?'),('Programmer''s Guide'),('A.B.C''s of Coding')) x(input)\
where to_tsvector('english', input) @@ plainto_tsquery('english', 'programmers');
input | to_tsvector
--------------------+-----------------------
Programmer's Guide | 'guid':3 'programm':1
(1 row)
这里plainto_tsquery
分析用户输入字符串,并生成一个查询,其中查询中的每个不间断字必须由tsvector匹配。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.