检查数组与 Spring JPA 和规范 API 的交集

问题描述 投票:0回答:1

我有一个代表一篇文章的模型:

public class Article {

    @Id
    private Integer id;
    private String title;
    private String content;
    // ...
    // plenty of other article properties, used to classify and filter over them
    // ...
    @ElementCollection
    private Set<String> tags;
}

以及其他人用来动态构建查询的规范:

...
    public static Specification<Article> byTagAnyOf(Set<String> referenceTags) {
        return ((root, query, builder) -> {
           if (CollectionUtils.isEmpty(referenceTags)) {
               return builder.conjunction();
           }
            return builder.or(referenceTags.stream()
                    .map(tag -> builder.isMember(tag, root.get("tags")))
                    .toArray(Predicate[]::new));
        });
    }
...

这个解决方案实际上有效,但是创建了一个包含大量

or
语句的查询,执行
tag
元素的选择,这会导致性能问题。

有没有办法通过加入

referenceTags
或通过规范 API 选择 except 来执行数组相交检查?

spring jpa specifications
1个回答
0
投票

由于性能问题,您可能有多种原因,对我来说调查所有这些原因都是有意义的。

关于你的问题,你有很多 OR 条件,因为是你用

builder.or
指定了这个。

老实说,我不明白你的数组交集是什么意思,但我有一个问题要问你:你是否考虑使用 IN 语句而不是所有可能标签的 OR ?

我建议您检查的第二件事是生成的查询,请验证数据库中触发的查询是什么(如果激活它,您可以在日志中找到它),至少对我来说事情会更清楚。

我完全理解您正在使用规范动态生成查询,这没有任何问题,但是您确实正在生成“不可预测”的查询,这将迫使您在数据库中创建所有可能的索引组合(这是疯狂地为所有可能的组合生成索引)。

OR 子句链可能会阻止数据库使用正确的索引,请尝试使用 IN 语句并让我知道。

总而言之,我的建议是:

  1. 我强烈建议您考虑过滤所有可能字段的可能性,因为这会给数据库带来压力,也是导致性能问题的原因。
  2. 在数据库中生成正确的索引。
  3. 分析您的查询以查看数据库的行为方式。
  4. 考虑使用 IN 语句而不是 OR 链
© www.soinside.com 2019 - 2024. All rights reserved.