【发布时间】:2022-06-11 04:19:37
【问题描述】:
在我的 MySQL 数据库 (8.0.23) 上,我有一个 JSON 列,它是
multi value indexed
。
我想使用 QueryDSL 来使用带有
JSON_CONTAINS
的索引进行查询。
我已验证该列已正确编入索引,并且在我运行查询时正在使用该索引;例如,
EXPLAIN SELECT *
FROM user u
WHERE JSON_CONTAINS(JSON_EXTRACT(u.alias,'$'), JSON_QUOTE('John'));
表示正按预期使用多值索引。
到目前为止,我已经尝试过
Expressions.booleanTemplate("JSON_CONTAINS(JSON_EXTRACT({0}, '$'), JSON_QUOTE({1})) = 1", expression, str)
并以
BooleanExpression
作为谓词,以使用 QueryDSL 实现相同的目的;请注意,如果没有
= 1
,执行它会抛出以下错误。
java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected AST node
at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:362)
at org.hibernate.hql.internal.ast.QuerySyntaxException.convert(QuerySyntaxException.java:74)
at org.hibernate.hql.internal.ast.ErrorTracker.throwQueryException(ErrorTracker.java:93)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:282)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:192)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:144)
at org.hibernate.engine.query.spi.HQLQueryPlan.(HQLQueryPlan.java:113)
at org.hibernate.engine.query.spi.HQLQueryPlan.(HQLQueryPlan.java:73)
at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:162)
at org.hibernate.internal.AbstractSharedSessionContract.getQueryPlan(AbstractSharedSessionContract.java:636)
at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:748)
确实,
= 1
似乎阻止了索引用于同一查询。例如,
EXPLAIN SELECT *
FROM user u
WHERE JSON_CONTAINS(JSON_EXTRACT(u.alias,'$'), JSON_QUOTE('John')) = 1;
表示没有使用索引。
!= 0
、
IS TRUE
或
IS NOT FALSE
也是如此
因此,我遇到的问题是,对于 QueryDSL,我还没有找到在
JSON_CONTAINS(JSON_EXTRACT(u.alias,'$'), JSON_QUOTE('John'))
上没有
= 1
结尾的
BooleanExpression
的方法。但是,当
JSON_CONTAINS
末尾有
= 1
时,MySQL 似乎没有使用多值索引
我尝试了来自 https://stackoverflow.com/a/68684997/18476687 的建议,但到目前为止没有运气。
有没有办法在 QueryDSL 上不使用
= 1
来表示
JSON_CONTAINS(JSON_EXTRACT(u.alias,'$'), JSON_QUOTE('John'))
,以便使用多值索引?