HQL Hibernate查询:搜索检查列表是否包含另一个列表的所有元素

4

我遇到了一个问题,无法想出解决方案。 所以我有这段代码:

public List<Post> getPosts(List<PostStrategy> allowedStrategyList, Set<Tag> allowedTags, int page, int resultsPerPage) {
    return entityManager.createQuery("select post from Post post join post.tags tag where post.postStrategy in (:postStrategyList) and (:allowedTagsSize = 0 or tag in (:allowedTags))", Post.class)
            .setParameter("postStrategyList", allowedStrategyList)
            .setParameter("allowedTags", allowedTags)
            .setParameter("allowedTagsSize", allowedTags.size())
            .setFirstResult((page - 1) * resultsPerPage)
            .setMaxResults(resultsPerPage)
            .getResultList();
}

这段代码存在的问题在于,当有人使用多个标签进行搜索(例如:#video、#image),它会返回包含这两种标签和其中一种标签的帖子。
我希望它能够返回同时包含 #video 和 #image 标签的帖子。为了实现这一点,我需要检查列表是否包含另一个列表的所有元素。
我搜索了一段时间,并尝试了不同的方法,但是目前还没有找到解决方法。
我曾尝试用“post.tags in (:allowedTags)”替换“tag in (:allowedTags)”,但是这会导致 SQL 无效。
1个回答

0
两年后,我得到了答案。现在我正在使用Spring Boot和SpEL表达式,请耐心等待。这个查询做的不仅仅是我的原始想法,但你可以从中提取你需要的内容。
@Override
@Query("select p from PostSnapshot p where " +
        // Tags
        "(:#{#query.withTags.size()} = 0 or p.id in (" +
        "select post.id from PostSnapshot post inner join post.tags tag " +
        "where tag.value in (:#{#query.withTags}) " +
        "group by post.id " +
        "having count(distinct tag.value) = :#{#query.withTags.size() * 1L}" +
        ")) and (:#{#query.withoutTags.size()} = 0 or p.id not in (" +
        "select post.id from PostSnapshot post inner join post.tags tag " +
        "where tag.value in (:#{#query.withoutTags}) " +
        "group by post.id " +
        "having count(distinct tag.value) = :#{#query.withoutTags.size() * 1L}" +
        ")) " +
        // Artists
        "and (:#{#query.withArtists.size()} = 0 or p.id in (" +
        "select post.id from PostSnapshot post inner join post.artists artist " +
        "where artist.preferredNickname in (:#{#query.withArtists}) " +
        "group by post.id " +
        "having count(distinct artist.preferredNickname) = :#{#query.withArtists.size() * 1L}" +
        ")) and (:#{#query.withoutArtists.size()} = 0 or p.id not in (" +
        "select post.id from PostSnapshot post inner join post.artists artist " +
        "where artist.preferredNickname in (:#{#query.withoutArtists}) " +
        "group by post.id " +
        "having count(distinct artist.preferredNickname) = :#{#query.withoutArtists.size() * 1L}" +
        ")) " +
        // Title like words
        "and lower(p.title) like concat('%', lower(:#{(#query.words.isEmpty()) ? '' : #query.words.toArray()[0]}) ,'%')" +
        // OwnerId
        "and p.ownerId = :ownerId")
Page<PostSnapshot> findAllByOwnerIdAndQuery(@Param("ownerId") UUID ownerId, @Param("query") PostQuerySearchDTO query, Pageable pageable);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接