You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot实现多Genre全匹配查询的方法求助

问题:查询包含所有指定Genre的内容

当前Spring Boot项目中,通过Genre数组查询内容时,返回的是包含任意指定Genre的结果,但实际需求是返回包含所有指定Genre的内容。比如movie1包含drama和comedy,movie2包含crime和drama,当查询条件为comedy和drama时,只应返回movie1,但现有实现会同时返回两者。

现有代码

Repository

@Query(value = "SELECT CONTENTS.ID, CONTENTS.CONTENT_TYPE, CONTENTS.DESCRIPTION, CONTENTS.IMAGE_URL, CONTENTS.TRAILER_URL, CONTENTS.IS_AGE_RESTRICTED, CONTENTS.RELEASE_DATE, CONTENTS.RUNTIME, CONTENTS.SPOKEN_LANGUAGE, CONTENTS.TITLE, CONTENTS.TITLE, GROUP_CONCAT(GENRES.NAME) AS GENRE FROM CONTENTS INNER JOIN GENRES ON CONTENTS.ID=GENRES.CONTENT_ID WHERE GENRE IN (:search) GROUP BY CONTENTS.ID", nativeQuery = true)
List<Content> findContentByGenre(String[] search);

Controller

@GetMapping("findAllContentByGenres/genre")
public List<Content> getAllContentByGenres(@Param("genre") String[] genre){
    return contentService.getAllContentByGenres(genre);
}

Service

public List<Content> getAllContentByGenres(String[] genre) {
    return contentRepository.findContentByGenre(genre);
}

解决方案

核心是修改Repository的SQL查询,通过分组后统计匹配的Genre数量,精准筛选出包含所有指定Genre的内容,比你提供的PHP模糊拼接方案更可靠。

修改后的Repository

@Query(value = "SELECT CONTENTS.ID, CONTENTS.CONTENT_TYPE, CONTENTS.DESCRIPTION, CONTENTS.IMAGE_URL, CONTENTS.TRAILER_URL, CONTENTS.IS_AGE_RESTRICTED, CONTENTS.RELEASE_DATE, CONTENTS.RUNTIME, CONTENTS.SPOKEN_LANGUAGE, CONTENTS.TITLE, GROUP_CONCAT(GENRES.NAME) AS GENRE " +
        "FROM CONTENTS " +
        "INNER JOIN GENRES ON CONTENTS.ID=GENRES.CONTENT_ID " +
        "WHERE GENRES.NAME IN (:search) " +
        "GROUP BY CONTENTS.ID " +
        "HAVING COUNT(DISTINCT GENRES.NAME) = :searchSize", nativeQuery = true)
List<Content> findContentByAllGenres(@Param("search") String[] search, @Param("searchSize") int searchSize);

修改后的Service

public List<Content> getAllContentByGenres(String[] genre) {
    // 传入查询数组的长度,用于SQL中的计数判断
    return contentRepository.findContentByAllGenres(genre, genre.length);
}

逻辑说明

  1. 保留IN (:search)筛选出包含任意指定Genre的关联记录,但通过GROUP BY CONTENTS.ID将同一内容的所有Genre记录分组
  2. 新增HAVING COUNT(DISTINCT GENRES.NAME) = :searchSize:只有当分组内匹配的不同Genre数量和查询条件的数量完全一致时,才返回该内容,确保内容包含所有指定Genre
  3. 为什么不用你提供的PHP拼接逻辑?因为LIKE '%xxx%'依赖GROUP_CONCAT后的字符串匹配,容易出现误匹配(比如Genre为"dark-comedy"会被"comedy"匹配到),而计数方案更精准。

Controller层无需修改,保持原有代码即可。

内容的提问来源于stack exchange,提问作者Konstantinos Orfeas Kiourtidis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 19:40:57