MongoDB使用populate关联分类后筛选分类ID在指定数组的产品
实现方案
有两种实现方式,优先推荐查询阶段直接过滤的方案,性能更高。
方案1:查询阶段直接过滤(推荐)
直接在MongoDB查询时就加入分类ID的匹配条件,避免拉取全量无用数据,可利用索引提升查询效率,Mongoose会自动将数组中的字符串ID转换为ObjectId进行匹配:
const mongoose = require('mongoose'); async sortCatalog(arr) { // 直接在find中添加category的$in匹配条件 const products = await CatalogModel.find({ category: { $in: arr } }).lean() .populate("category", "name") .select('-__v'); // 此时products已经是筛选后符合分类要求的产品 console.log("筛选后的产品", products) }
方案2:内存筛选(仅适用于必须先获取全量产品的特殊场景)
如果你确实需要先拿到全量产品数据再做筛选,可以在拿到populate后的结果后,手动过滤数组,注意要把ObjectId转为字符串再和传入的ID数组匹配:
async sortCatalog(arr) { const products = await CatalogModel.find().lean() .populate("category", "name") .select('-__v'); // 内存过滤:将category的_id转成字符串后判断是否在目标数组中 const filteredProducts = products.filter(item => { return arr.includes(item.category._id.toString()) }) console.log("筛选后的产品", filteredProducts) }
注意事项
- 两种方案对比:数据量大于100条时优先用方案1,方案2全量拉取数据再过滤会浪费数据库IO和内存资源
- 匹配时注意类型一致:MongoDB的_id是ObjectId类型,和字符串ID直接做全等判断会返回false,需要统一转成字符串或者统一转成ObjectId再匹配
内容的提问来源于stack exchange,提问作者Evgeny Alekseev
相关产品推荐
相关产品推荐

