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

如何在Mongoose/MongoDB中通过关联字段搜索商品?

通过分类字段搜索商品的实现方案

核心思路

由于Product与Category是一对多关联,Product的category字段存储的是分类ID,要实现按分类名称/描述搜索商品,有两种可行思路:要么先筛选出匹配的分类ID,再用ID查询对应商品;要么直接通过MongoDB的关联聚合查询完成匹配。

具体实现

方式一:先查分类ID,再关联商品

在/src/modules/products/products.service.ts的findAll方法中,先调用分类服务获取匹配的分类,再用分类ID查询商品:

async findAll(searchText?: string) {
  let queryCondition = {};

  if (searchText) {
    // 搜索匹配name或description的分类
    const matchedCategories = await this.categoriesService.findAll({
      $or: [
        { name: new RegExp(searchText, 'i') },
        { description: new RegExp(searchText, 'i') }
      ]
    });

    // 提取匹配分类的ID集合
    const targetCategoryIds = matchedCategories.map(category => category._id);

    // 组合查询条件:商品自身字段匹配 或 所属分类ID在目标集合中
    queryCondition = {
      $or: [
        { name: new RegExp(searchText, 'i') },
        { price: new RegExp(searchText, 'i') },
        { category: { $in: targetCategoryIds } }
      ]
    };
  }

  return this.productModel.find(queryCondition);
}

依赖注入说明:需要在ProductsService中注入CategoriesService,确保能调用分类查询方法:

constructor(
  @InjectModel(Product.name) private readonly productModel: Model<Product>,
  private readonly categoriesService: CategoriesService
) {}

方式二:MongoDB聚合关联查询

直接通过$lookup关联分类集合,一次聚合完成所有匹配逻辑:

async findAll(searchText?: string) {
  if (!searchText) {
    return this.productModel.find();
  }

  return this.productModel.aggregate([
    // 关联分类集合,获取商品对应的分类信息
    {
      $lookup: {
        from: 'categories', // 注意这里是MongoDB中的分类集合名称,需与模型对应
        localField: 'category',
        foreignField: '_id',
        as: 'categoryDetail'
      }
    },
    // 匹配条件:商品自身字段匹配,或分类的name/description匹配
    {
      $match: {
        $or: [
          { name: new RegExp(searchText, 'i') },
          { price: new RegExp(searchText, 'i') },
          { 'categoryDetail.name': new RegExp(searchText, 'i') },
          { 'categoryDetail.description': new RegExp(searchText, 'i') }
        ]
      }
    },
    // 可选:如果不需要返回分类详情,移除该字段
    {
      $unset: 'categoryDetail'
    }
  ]);
}

方案对比

  • 方式一逻辑简单直观,适合数据量较小的场景,便于维护和调试;
  • 方式二通过单次聚合查询完成,减少数据库交互次数,适合数据量较大的场景,但需要注意集合名称的准确性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 01:35:22