【问题标题】:Using Postgres SIMILAR TO with Spring Data to match substring in column使用 Postgres SIMILAR TO 和 Spring Data 来匹配列中的子字符串
【发布时间】:2021-07-07 00:20:05
【问题描述】:

我在列中有一条记录,其值为“非常漂亮的 BMW 4 轮驱动 i5”。

如果我提供此值的子字符串,我如何进行查询以找到此值?假设我想通过提供这个“BMW i5”来找到它?

如果我使用 LIKE 方法,那么它期望单词按顺序排列。

@Query("SELECT p FROM Product p WHERE p.name LIKE CONCAT('%',:name,'%')")

我正在使用带有 Spring DATA 的 Spring Boot。数据库是postgres。

如果我用这个查询在 Postgres 上搜索字符串,我可以找到它,所以问题是如何使用 Spring DATA 来做到这一点:

select name from product WHERE name similar TO '%((BMW) | (i5))%'

【问题讨论】:

    标签: sql postgresql spring-boot spring-data pattern-matching


    【解决方案1】:

    使用 Postgres 类似...

    不要。永远不要使用SIMILAR TO。这完全没有意义。见:

    使用正则表达式匹配运算符~(或可能不区分大小写的变体~*)可以更快地在字符串中的任何位置查找部分匹配。要以任意顺序匹配 two 字符串,请使用 two 表达式以保持简单。喜欢:

    SELECT * FROM Product p WHERE p.name ~ 'BMW' AND p.name ~ 'i5';
    

    但我怀疑你想要 'i5' 'BMW' 之后(中间有一些噪音或没有噪音):

    SELECT * FROM Product p WHERE p.name ~ 'BMW.*i5';
    

    或者:

    SELECT * FROM Product p WHERE p.name LIKE '%BMW%i5%';
    

    两者都可以通过三元组索引来支持,例如:

    CREATE INDEX ON Product USING gin (name gin_trgm_ops);
    

    首先需要附加模块pg_trgm。见:

    使用text search。然后你可以传递一个包含多个单词(词位)的字符串。您的查询可能如下所示:

    ... WHERE to_tsvecor(p.name) @@ plainto_tsquery('simple', 'BMW i5');
    

    或者使用词组搜索来查找'BMW'后跟'i5'

    ... WHERE to_tsvecor(p.name) @@ phraseto_tsquery('simple', 'BMW i5')
    

    见:

    文本搜索功能强大,但您可能需要先熟悉它。该手册提供了您需要了解的所有内容。索引可能如下所示:

    CREATE INDEX ON Product USING GIN (to_tsvector('simple', name));
    

    进一步阅读:

    【讨论】:

    • 谢谢,但是如何使用 Spring Data 将其转换为查询?
    • @AhmedAziz:对 Spring Data 了解不多。但是,最终,它将被转换回 SQL 形式,这就是发送到数据库的内容。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-28
    • 1970-01-01
    • 1970-01-01
    • 2021-08-13
    • 2021-07-15
    • 2020-02-29
    • 2013-06-08
    相关资源
    最近更新 更多