发布
社区首页 >问答首页 >Postgres全文搜索部分单词

Postgres全文搜索部分单词
EN

Stack Overflow用户
提问于 2022-02-15 16:39:02
回答 2查看 958关注 0票数 0

我已经看到了很多像这样的例子:postgres full text search like operator

它们都指定您可以执行如下前缀搜索:

代码语言:javascript
代码运行次数:0
复制
SELECT * 
FROM eventlogging 
WHERE description_tsv @@ to_tsquery('mess:*');

它将检索一个类似于“消息”的单词

然而,我在任何地方都看不到的是,是否有办法搜索一个词的不同部分,如后缀?

我现在遇到麻烦的例子是:

代码语言:javascript
代码运行次数:0
复制
CREATE TABLE IF NOT EXISTS project (
    id VARCHAR NOT NULL,
    org_name VARCHAR NOT NULL DEFAULT '',
    project_name VARCHAR NOT NULL DEFAULT ''
);

insert into project(id, org_name, project_name) values ('123', 'org', 'proj');
insert into project(id, org_name, project_name) values ('456', 'huh', 'org');
insert into project(id, org_name, project_name) values ('789', 'orgs', 'project');


CREATE OR REPLACE FUNCTION get_projects(query_in VARCHAR)
RETURNS TABLE (id VARCHAR, org_name VARCHAR, project_name VARCHAR) AS $$
BEGIN
  RETURN QUERY
  SELECT * FROM project WHERE (
    to_tsvector('simple', coalesce(project.project_name, '')) || 
    to_tsvector('simple', coalesce(project.org_name, ''))
  ) @@ to_tsquery('simple', query_in);
END;
$$ LANGUAGE plpgsql;

以下示例返回:

代码语言:javascript
代码运行次数:0
复制
select * from get_projects('org');

id  org_name    project_name
----------------------------
123 org         proj
456 huh         org

我的问题是:为什么它不返回orgs?类似地,如果我搜索proj,我只会得到名为"proj“的项目,而不会得到名为”project“的项目。

加分:如果我搜索一个子字符串,我如何获得结果?例如,如果我搜索字符串jec,我想要返回名为project的项目。我并不是真的在寻找模糊搜索,但我会说我正在寻找子字符串搜索。

我使用to_tsquery完全错误吗?我也尝试过plainto_tsquery,我尝试使用english而不是simple,但是有几个引用被认为是简单的。

EN

回答 2

Stack Overflow用户

发布于 2022-02-15 17:15:19

全文搜索不同于子字符串搜索。全文搜索就是搜索整个单词,从索引中省略频繁出现的单词,忽略拐点等等。PostgreSQL全文搜索允许前缀搜索,在一定程度上扩展了这一点。

要搜索子字符串,必须使用以下条件进行搜索

代码语言:javascript
代码运行次数:0
复制
WHERE word ~ 'suffix\M'

(这将是带有正则表达式匹配运算符~的后缀搜索。)

为了加速这样的搜索,创建一个trigram索引:

代码语言:javascript
代码运行次数:0
复制
CREATE EXTENSION IF NOT EXISTS pg_trgm;

CREATE INDEX ON tab USING gin (doc gin_trgm_ops);
票数 1
EN

Stack Overflow用户

发布于 2022-02-15 18:42:49

所谓的前缀搜索实际上并不属于全文搜索。我认为这是因为,考虑到令牌无论如何都会存储在btree中,所以补充说“功能”是免费的。在FTS上下文中没有提到其他类型的部分匹配,因为它们不存在。

您将讨论:*符号FTS中确实存在的部分匹配。但是在你的例子中,你实际上并没有使用它。这就是为什么你看不到它的作用,因为你不使用它。如果你确实使用了它,它就会起作用:

代码语言:javascript
代码运行次数:0
复制
select * from get_projects('org:*');

但根据你的描述,听起来你一开始就不想要FTS。您希望喜欢或regex,可能需要来自pg_trgm的索引支持。

,但是有几个参考文献说是简单的。

很难知道匿名引用的判断有多好,但是如果您只想使用“简单”而不是最有可能的话,您就不应该首先使用FTS。“简单”对于分析、学习或调试真实的FTS情况很有用,并且可以用作建立更复杂配置的基线。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71130150

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档