Mongoose关联查询问题:如何按关联Store的name筛选Product数据
问题描述
需要查询所有属于指定名称Store的Product数据,Product的store字段存储的是Store的_id,需同时获取关联的Store信息。
尝试过两种写法但均不符合需求:
- 直接使用
Product.find({ 'store.name': "Ejemplo1" }),由于Product集合仅存储Store的_id,没有name字段,无法匹配条件,返回空结果。 - 在
populate中添加match选项,仅会将不符合条件的Product的store字段设为null,不会过滤掉整个Product文档,返回了全量Product集合。
可行解决方案
方案一:先查Store ID,再关联查询Product(推荐)
这是最直观高效的方式,先定位目标Store的_id,再用该ID查询关联的Product,最后填充Store信息。
// 1. 查询目标Store的信息 const targetStore = await Store.findOne({ name: "Store1" }); if (!targetStore) { return []; // 处理Store不存在的情况 } // 2. 查询关联该Store的Product并填充Store信息 const products = await Product.find({ store: targetStore._id }) .populate('store', 'name');
方案二:使用MongoDB聚合管道(一次性查询)
通过聚合管道的$lookup关联Store集合,再筛选出符合条件的文档,适合需要单次数据库请求的场景。
const products = await Product.aggregate([ // 关联Store集合(注意from的值是MongoDB实际集合名,通常为模型名小写复数) { $lookup: { from: 'stores', localField: 'store', foreignField: '_id', as: 'store' } }, // 将store数组转为单个对象(一对一关联场景) { $unwind: '$store' }, // 筛选Store名称匹配的文档 { $match: { 'store.name': 'Store1' } }, // 可选:按需保留字段 { $project: { _id: 1, 'store.name': 1 // 可添加其他需要保留的Product字段 } } ]);
方案三:Populate后过滤(不推荐大数据量)
若坚持使用populate,可在查询完成后过滤掉store为null的文档,但此方式会先查询全量Product,数据量大时性能较差。
const allProducts = await Product.find({}) .populate({ path: 'store', match: { name: 'Store1' }, select: 'name -_id' }); // 过滤掉store为空的Product const filteredProducts = allProducts.filter(product => product.store !== null);
内容的提问来源于stack exchange,提问作者miguel morillo
相关产品推荐
相关产品推荐

