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

Java多条件搜索结果异常:循环后仅保留最后一次搜索结果

食谱多条件搜索结果丢失问题解决

问题描述

开发支持多搜索词和多搜索类型的食谱搜索页面时,遇到结果丢失问题:单个搜索条件可正常返回结果,但多条件搜索时,页面仅展示最后一次搜索的结果。当前搜索词和搜索类型能正常传递,但无法聚合所有符合条件的结果并返回给页面。

现有代码

控制器代码

@PostMapping("adv-search/results")
public String displayAdvancedSearchResults(Model model , @RequestParam String searchType, @RequestParam String searchTerm) {

    Iterable<Recipe> recipes = null;
    String[] searchTerms = searchTerm.split(",");
    String[] searchTypes = searchType.split(",");

    for (int i=0; i < searchTerms.length; i++) {
        String sTe = searchTerms[i];
        String sTy = searchTypes[i];

        if (sTe.toLowerCase().equals("all") || sTe.equals("")){
            recipes = RecipeRepository.findAll();
        } else {
            recipes = RecipeData.findByColumnAndValue(sTy, sTe, RecipeRepository.findAll());
        }

    }

    model.addAttribute("columns", columnChoices);
    model.addAttribute("title", "Recipes with " + columnChoices.get(searchType) + ": " + searchTerm);
    model.addAttribute("recipes", recipes);

    return "adv-search";

}

RecipeData类代码

public class RecipeData {

    public static ArrayList<Recipe> findByColumnAndValue(String column, String value, Iterable<Recipe> allRecipes) {

        ArrayList<Recipe> results = new ArrayList<>();

        if (value.toLowerCase().equals("all")){
            return (ArrayList<Recipe>) allRecipes;
        }

        if (column.equals("all")){
            results = findByValue(value, allRecipes);
            return results;
        }
        for (Recipe recipe : allRecipes) {

            String aValue = getFieldValue(recipe, column);

            if (aValue != null && aValue.toLowerCase().contains(value.toLowerCase())) {
                results.add(recipe);
            }
        }

        return results;
    }

    public static String getFieldValue(Recipe recipe, String fieldName) {
        String theValue;
        if (fieldName.equals("name")){
            theValue = recipe.getName();
            System.out.println(recipe.getName());
        } else if (fieldName.equals("ingredients")){
            theValue = recipe.getIngredientList().toString();
            System.out.println(recipe.getIngredientList().toString());
        } else { //prints [com.launchcode.recipeproject.models.Tag@20] instead of tags
            theValue = recipe.getTags().toString().toString();
            System.out.println(recipe.getTags().toString().toString());
        }

        return theValue;
    }

    public static ArrayList<Recipe> findByValue(String value, Iterable<Recipe> allRecipes) {
        String lower_val = value.toLowerCase();

        ArrayList<Recipe> results = new ArrayList<>();

        for (Recipe recipe : allRecipes) {

            if (recipe.getName().toLowerCase().contains(lower_val)) {
                results.add(recipe);
            } else if (recipe.getIngredientList().toString().toLowerCase().contains(lower_val)) {
                results.add(recipe);
            } else if (recipe.getTags().toString().toLowerCase().contains(lower_val)) {
                results.add(recipe);
            } else if (recipe.toString().toLowerCase().contains(lower_val)) {
                results.add(recipe);
            }

        }

        return results;
    }

}

问题根源

  1. 循环中每次都会覆盖recipes变量的引用,最终仅保留最后一次循环的查询结果,未实现多条件结果聚合。
  2. 每次查询都基于全量食谱数据(RecipeRepository.findAll()),而非上一次的过滤结果,导致多条件无法叠加过滤。

修复方案

1. 修改控制器逻辑,实现多条件叠加过滤(交集逻辑)

将结果存储改为List<Recipe>,初始化为全量数据,之后每次循环基于当前结果进行过滤,保留符合所有条件的食谱:

@PostMapping("adv-search/results")
public String displayAdvancedSearchResults(Model model, @RequestParam String searchType, @RequestParam String searchTerm) {

    List<Recipe> recipes = new ArrayList<>();
    String[] searchTerms = searchTerm.split(",");
    String[] searchTypes = searchType.split(",");

    // 初始化结果为全量食谱
    recipes.addAll(RecipeRepository.findAll());

    for (int i = 0; i < searchTerms.length; i++) {
        String sTe = searchTerms[i].trim(); // 去除输入空格,避免无效搜索词
        String sTy = searchTypes[i].trim();

        if (sTe.toLowerCase().equals("all") || sTe.isEmpty()) {
            // 该条件为"all"或空,跳过过滤,保持当前结果
            continue;
        }

        // 基于当前结果进行下一轮过滤,而非全量数据
        recipes = RecipeData.findByColumnAndValue(sTy, sTe, recipes);
    }

    model.addAttribute("columns", columnChoices);
    model.addAttribute("title", "Recipes with " + columnChoices.get(searchType) + ": " + searchTerm);
    model.addAttribute("recipes", recipes);

    return "adv-search";
}

2. 优化标签搜索显示(可选)

原getFieldValue方法中,recipe.getTags().toString()会输出对象地址而非标签名称,需重写Tag类的toString()方法:

public class Tag {
    // ... 原有属性和方法

    @Override
    public String toString() {
        return this.getName(); // 假设Tag类有getName()方法返回标签名称
    }
}

3. 若需并集逻辑(满足任意条件)

如果需要展示符合任意一个搜索条件的食谱,修改控制器中的循环逻辑,将每次查询结果合并并去重:

// 初始化空集合,自动去重
Set<Recipe> recipeSet = new HashSet<>();

for (int i = 0; i < searchTerms.length; i++) {
    String sTe = searchTerms[i].trim();
    String sTy = searchTypes[i].trim();

    if (sTe.toLowerCase().equals("all") || sTe.isEmpty()) {
        recipeSet.addAll(RecipeRepository.findAll());
        continue;
    }

    List<Recipe> currentResults = RecipeData.findByColumnAndValue(sTy, sTe, RecipeRepository.findAll());
    recipeSet.addAll(currentResults);
}

// 转换为List传给页面
List<Recipe> recipes = new ArrayList<>(recipeSet);

内容的提问来源于stack exchange,提问作者user22311577

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 09:25:48