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

如何使用Mongoose的aggregate实现分组后的搜索过滤功能?

使用Mongoose Aggregate替代内存过滤实现搜索功能

你当前的代码已经实现了搜索需求,但确实可以通过Mongoose的aggregate管道直接完成过滤逻辑,把计算压力从服务端内存转移到数据库,提升性能(尤其是数据量较大时)。下面是具体的优化方案:

原代码回顾

const getQuoteAuthorSearchedResult = async (req, res) => {
  try {
    const searchWord = req.params.searchWord

    const uniqueQuoteAuthors = await QuoteModel.aggregate().group({
      _id: "$author",
      count: { $sum: 1 },
    });

    const filteredData = await uniqueQuoteAuthors.filter((value) => {
      return value._id.toLowerCase().includes(searchWord.toLowerCase());
    });

    res.status(200).json({
      results: filteredData
    })
  } catch (error) {
    res.status(401).json({ success: false });
  }
};

优化方案:用Aggregate管道完成过滤+分组

方案1:先过滤再分组(推荐,性能更优)

先通过$match阶段筛选出包含关键词的作者文档,再进行分组统计,数据库只处理符合条件的数据,减少不必要的计算:

const getQuoteAuthorSearchedResult = async (req, res) => {
  try {
    const searchWord = req.params.searchWord;
    // 构造不区分大小写的正则表达式
    const searchRegex = new RegExp(searchWord, 'i');

    const filteredData = await QuoteModel.aggregate([
      // 第一步:匹配包含关键词的作者
      {
        $match: {
          author: searchRegex
        }
      },
      // 第二步:分组统计每个作者的引用数量
      {
        $group: {
          _id: "$author",
          count: { $sum: 1 }
        }
      }
    ]);

    res.status(200).json({ results: filteredData });
  } catch (error) {
    res.status(500).json({ success: false, error: error.message });
  }
};

方案2:先分组再过滤(与原逻辑一致,性能稍差)

如果需要保留「先获取所有唯一作者,再过滤」的逻辑,也可以在$group之后添加$match阶段:

const getQuoteAuthorSearchedResult = async (req, res) => {
  try {
    const searchWord = req.params.searchWord;
    const searchRegex = new RegExp(searchWord, 'i');

    const filteredData = await QuoteModel.aggregate([
      {
        $group: {
          _id: "$author",
          count: { $sum: 1 }
        }
      },
      // 在分组结果中过滤符合条件的作者
      {
        $match: {
          _id: searchRegex
        }
      }
    ]);

    res.status(200).json({ results: filteredData });
  } catch (error) {
    res.status(500).json({ success: false, error: error.message });
  }
};

进阶方案:MongoDB Atlas全文搜索(复杂场景适用)

如果需要更强大的搜索能力(比如分词、模糊匹配、容错处理),可以使用MongoDB Atlas的全文搜索功能,提前创建针对author字段的全文索引后,用$search阶段实现:

const getQuoteAuthorSearchedResult = async (req, res) => {
  try {
    const searchWord = req.params.searchWord;

    const filteredData = await QuoteModel.aggregate([
      {
        $search: {
          index: 'author_search', // 提前在Atlas控制台创建的全文索引名称
          text: {
            query: searchWord,
            path: 'author',
            fuzzy: { maxEdits: 1 } // 允许1个字符的拼写错误,提升搜索容错性
          }
        }
      },
      {
        $group: {
          _id: "$author",
          count: { $sum: 1 }
        }
      }
    ]);

    res.status(200).json({ results: filteredData });
  } catch (error) {
    res.status(500).json({ success: false, error: error.message });
  }
};

优化优势

  • 减少服务端内存占用:不需要把所有分组结果加载到内存再过滤
  • 提升性能:数据库层面的过滤和分组利用了MongoDB的查询优化,比内存过滤效率更高
  • 可扩展性:支持更复杂的搜索逻辑(如全文搜索)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 09:15:00