Postgresql 搜索字符串中的单个单词
我知道全文搜索,但它只匹配您对单个单词的查询。我想选择包含以我的查询中的单词开头的单词的字符串。例如,如果我搜索:Postgresql 搜索字符串中的单个单词,postgresql,search,full-text-search,Postgresql,Search,Full Text Search,我知道全文搜索,但它只匹配您对单个单词的查询。我想选择包含以我的查询中的单词开头的单词的字符串。例如,如果我搜索: appl 以下内容应匹配: a really nice application apples are cool appliances 因为所有这些字符串都包含以appl开头的单词。此外,如果我可以选择匹配的单词数量,并根据这些单词进行排序,那就太好了 如何在PostgreSQL中实现这一点 SELECT * FROM some_table WHERE some_field LI
appl
以下内容应匹配:
a really nice application
apples are cool
appliances
因为所有这些字符串都包含以appl
开头的单词。此外,如果我可以选择匹配的单词数量,并根据这些单词进行排序,那就太好了
如何在PostgreSQL中实现这一点
SELECT * FROM some_table WHERE some_field LIKE 'appl%' OR some_field LIKE '% appl%';
至于计算匹配词的数量,我认为在postgres中动态计算会太昂贵(尽管可能其他人知道得更好)。一种方法是编写一个计算字符串中出现次数的函数,然后按myFunction('appl',some_字段)添加ORDER。尽管如此,这种方法非常昂贵(即速度慢),不推荐使用
对于这样的事情,你可能应该使用一个单独的/免费的全文搜索引擎,比如Sphinx search(google it),它专门用于这类事情
另一种方法是使用另一个表,其中包含关键字以及这些关键字在每个字符串中出现的次数。这意味着您需要存储您拥有的每个短语(例如真的很好的应用程序
),还需要将关键字存储在另一个表中(例如真的,2
,好,1
,应用程序,1
),并将该关键字表链接到完整的短语表。这意味着您必须在将字符串输入数据库时将其分解为关键字,并将其存储在两个位置。这是一个典型的空间与速度的权衡。前缀匹配与全文搜索
几年后,我重新审视这个问题,FTS确实支持前缀匹配。您的查询可以如下所示:
SELECT * FROM tbl
WHERE to_tsvector('simple', string) @@ to_tsquery('simple', 'appl:*');
注意tsquery
中附加的:*
。详情:
正则表达式替换
引述:
\m
。。仅在单词开头匹配
要按匹配数排序,可以使用
或:
演示所有三个
Postgres 9.3甚至为简单正则表达式提供了索引支持,并提供了trigram-GIN或GiST索引():
在pg_trgm中添加对正则表达式搜索索引的支持
(亚历山大·科罗特科夫)
我现在正在阅读类似的。如果搜索查询中有多个单词,该怎么办?如果我想搜索苹果和谷歌都是好公司,那该怎么办?从一些表格中选择*(一些字段如“appl%”或一些字段如“%appl%”)和(一些字段如“goog%”或一些字段如“%goog%”)代码>我想强调的是,这是一种黑客的方式。例如,以下内容与appl
搜索不匹配:“苹果是我的最爱!”男孩惊叫道。
因为appl前面有一个“苹果”。此外,您可能希望使用ILIKE(用于不区分大小写的搜索)。
SELECT * FROM tbl
WHERE string ~ '\mappl';
SELECT tbl_id, count(*) AS matches
FROM (
SELECT tbl_id, regexp_matches(string, '\mappl', 'g')
FROM tbl
WHERE string ~ '\mappl'
) sub
GROUP BY 1
ORDER BY 2 DESC;
SELECT tbl_id, string, count(*) - 1 AS matches
FROM (
SELECT tbl_id, string, regexp_split_to_table(string, '\mappl')
FROM tbl
WHERE string ~ '\mappl'
) sub
GROUP BY 1, 2
ORDER BY 3 DESC, 2, 1;