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

SpringBoot实现MongoDB数组字段匹配查询集合数据方案

实现方案

首先说下你现在的集合设计是合理的:同结构不同分类的数据合并到一个集合,用数组字段存分类标签,比拆成多个零散集合好维护,后续加新分类不用新建集合,扩展查询也方便。


1. 实体Model定义

你现在写的字段映射基本正确,补个MongoDB的集合映射注解就行,数组字段推荐换成List<String>,比原生String数组更适配Java的集合操作,和MongoDB的数组存储格式完全兼容:

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import java.util.List;

// 绑定MongoDB里的PackageHoliday集合
@Document(collection = "PackageHoliday")
public class PackageHoliday {
    @Id
    private String id;
    private String title;
    private String description;
    private String whatToDo;
    private List<String> packageHolidayType;

    // 自己补全getter、setter、构造函数,用Lombok的话直接类上加@Data注解省得写重复代码
}

2. 查询逻辑实现

两种写法选其一即可,简单场景优先用方法名派生查询,不用写额外实现代码:
第一种:直接继承MongoRepository写接口,Spring Data会自动根据方法名生成查询规则:

import org.springframework.data.mongodb.repository.MongoRepository;
import java.util.List;

public interface PackageHolidayRepository extends MongoRepository<PackageHoliday, String> {
    // 规则:查询packageHolidayType数组中包含传入分类值的所有文档
    List<PackageHoliday> findByPackageHolidayTypeContaining(String holidayType);
}

如果你的接口要实现「随机返回N条」的逻辑(从你写的接口名带Random判断有这个需求),用MongoTemplate写个聚合查询就行,把这段逻辑封装到Service层:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.stereotype.Service;
import java.util.List;

@Service
public class PackageHolidayService {
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private PackageHolidayRepository holidayRepository;

    // 按分类查全量数据
    public List<PackageHoliday> getListByType(String type) {
        return holidayRepository.findByPackageHolidayTypeContaining(type);
    }

    /**
     * 随机获取指定分类的N条套餐数据
     * @param type 分类值
     * @param limit 返回条数
     */
    public List<PackageHoliday> getRandomByType(String type, int limit) {
        Aggregation agg = Aggregation.newAggregation(
                // 第一步:过滤出匹配分类的文档
                Aggregation.match(Criteria.where("packageHolidayType").is(type)),
                // 第二步:随机抽样指定条数
                Aggregation.sample(limit)
        );
        return mongoTemplate.aggregate(agg, "PackageHoliday", PackageHoliday.class).getMappedResults();
    }
}

3. 控制器接口实现

不推荐为每个分类写重复的接口逻辑,把分类作为路径参数做通用接口就行,后续加新分类不用改代码;如果你一定要保留独立的接口地址,直接复用通用逻辑传固定参数即可。

推荐写法:通用接口

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;

@RestController
@RequestMapping("/api/holiday")
public class PackageHolidayController {
    @Autowired
    private PackageHolidayService holidayService;

    // 按分类查全量,例:请求 /api/holiday/type/escortedTours 就返回所有跟团游数据
    @GetMapping("/type/{holidayType}")
    public List<PackageHoliday> getListByType(@PathVariable String holidayType) {
        return holidayService.getListByType(holidayType);
    }

    // 按分类随机取N条,例:/api/holiday/random/escortedTours?limit=3 随机返回3条跟团游
    @GetMapping("/random/{holidayType}")
    public List<PackageHoliday> getRandomByType(@PathVariable String holidayType,
                                                @RequestParam(defaultValue = "3") int limit) {
        return holidayService.getRandomByType(holidayType, limit);
    }
}

适配你现有框架的写法

如果你要保留你之前写的/getRandomEscortedTours独立接口,直接调用Service方法传固定参数就行,不用重复写查询:

@GetMapping("/getRandomEscortedTours")
public List<PackageHoliday> getRandomEscortedTours() {
    return holidayService.getRandomByType("escortedTours", 3);
}

// 其他分类的独立接口同理,直接传对应分类值
@GetMapping("/getRandomIndependentTours")
public List<PackageHoliday> getRandomIndependentTours() {
    // 注意:你示例数据里的indepedentTours拼写少了个n,代码里的参数要和库里存的值完全一致,不然查不到数据
    return holidayService.getRandomByType("indepedentTours", 3);
}

踩坑提醒:注意核对库里存储的分类值拼写,示例数据里的独立游分类值是indepedentTours(正确拼写应为independentTours,少了一个n),代码里的查询参数必须和库内存储值完全匹配,否则会返回空结果。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 02:57:08