[英]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.