带有布尔全文搜索格式问题的spring jdbc准备语句

Posted

技术标签:

【中文标题】带有布尔全文搜索格式问题的spring jdbc准备语句【英文标题】:spring jdbc prepared statement with boolean fulltext search formatting issues 【发布时间】:2020-09-10 10:40:49 【问题描述】:

我有一个使用布尔全文搜索的 sql 查询:

SELECT
    *,
    MATCH (job_title) AGAINST ('"product manager"' in boolean mode) AS title_relevance_exact,
    MATCH (job_description) AGAINST ('"product manager"' in boolean mode) AS description_relevance_exact,
    MATCH (job_title) AGAINST ('product manager' in boolean mode) AS title_relevance_part,
    MATCH (job_description) AGAINST ('product manager' in boolean mode) AS description_relevance_part
FROM
    jobs
WHERE
    MATCH(job_title, job_description) AGAINST ('product manager') AND
    date_posted >= now() - INTERVAL 30 DAY
ORDER BY
    job_title LIKE 'product manager' DESC,
    title_relevance_exact DESC,
    description_relevance_exact DESC,
    title_relevance_part DESC,
    description_relevance_part DESC
LIMIT 300;

'"product manager"' 中的引号和语音标记对查询很重要。

当我将此查询作为 spring jdbc 准备好的语句运行时,我必须做一些工作来正确格式化字符串,因为如果我有 '?',jdbc 不会将其识别为参数:

String queryPrepared =
                "SELECT\n" +
                "   *,\n" +
                "   MATCH (job_title) AGAINST (? in boolean mode) AS title_relevance_exact,\n" +
                "   MATCH (job_description) AGAINST (? in boolean mode) AS description_relevance_exact,\n" +
                "   MATCH (job_title) AGAINST (? in boolean mode) AS title_relevance_part,\n" +
                "   MATCH (job_description) AGAINST (? in boolean mode) AS description_relevance_part\n" +
                "FROM\n" +
                "   jobs\n" +
                "WHERE\n" +
                "   MATCH(job_title, job_description) AGAINST (?) AND\n" +
                "   date_posted >= now() - INTERVAL 30 DAY\n" +
                "ORDER BY\n" +
                "   job_title LIKE ? DESC,\n" +
                "   title_relevance_exact DESC,\n" +
                "   description_relevance_exact DESC,\n" +
                "   title_relevance_part DESC,\n" +
                "   description_relevance_part DESC\n" +
                "LIMIT 500;";
        String param1 = String.format("'\"%1$s\"'", searchValue);
        String param2 = String.format("'%1$s'", searchValue);

        List<Map<String, Object>> resultPrepared = jdbcTemplate.queryForList(queryPrepared,
                new Object[] param1, param1, param2, param2, param2, param2);

但是查询没有产生正确的结果,结果不是预期的顺序。我只能假设发生这种情况是因为准备好的语句参数中的格式。但是添加参数后看不到查询的样子,请问如何调试呢?

【问题讨论】:

【参考方案1】:

您需要从值中删除单引号。 SQL 中的单引号分隔查询字符串中的字符串literal。设置参数值时,只需要设置不带单引号的字符串值即可。

因此,如果您想用参数替换文字 '"product manager"',则在查询中使用 ?(因此,不带单引号),并设置值 "product manager"(同样,不带单引号) ,作为 Java 字符串文字是 "\"product manager\""

在作为参数传递的值中使用单引号相当于使用 SQL 字符串文字 '''"product manager"'''

【讨论】:

以上是关于带有布尔全文搜索格式问题的spring jdbc准备语句的主要内容,如果未能解决你的问题,请参考以下文章

MySQL 全文搜索以布尔模式按相关性排序

MySQL ------ 全文本搜索( match和Against),以及查询扩展和 布尔方式(十七)

MySQL ------ 全文本搜索( match和Against),以及查询扩展和 布尔方式(十七)

ElasticSearch 全文搜索

带有全文搜索和项目的 Mongoose 子字段聚合

带有可为空参数的sql全文搜索