Mongoose pre(find)钩子中关联查询过滤数组字段的问题求助
解决方案:Mongoose中间件中基于文档字段过滤关联数据
问题根源
你使用的pre(/^find/)是查询中间件,此处的this指向Mongoose的Query对象,而非单个文档实例,因此无法直接访问文档的menuItem.store字段。同时bUnitSchema.menuItem.store是访问Schema的定义,并非具体文档的数据,这也是报错的原因。
可行方案
方案1:用post查询中间件处理已返回的文档
查询完成后,在post(/^find/)中间件中获取所有文档,逐个利用自身的menuItem.store值过滤关联数据:
bUnitSchema.post(/^find/, async function(docs) { for (const doc of docs) { await doc.populate({ path: "menuItem.product", select: { "storeId.$": 1 }, match: { "storeId.store": doc.menuItem.store } }); } });
- 必须使用
async/await,因为populate是异步操作,要确保每个文档完成关联后再返回结果。 - 注意字段名大小写:你之前代码里写的
"storeid.store"是小写d,要和Schema中定义的storeId保持一致,否则匹配会失效。
方案2:查询时传入自定义参数,在pre中间件中复用
如果需要在查询阶段就完成过滤,可以在调用find时传入目标storeId参数,再在pre中间件中提取使用:
调用查询的代码:
const targetStoreId = "你的目标storeId"; const bUnits = await BUnit.find(/* 你的查询条件 */).setOptions({ targetStoreId });
pre中间件代码:
bUnitSchema.pre(/^find/, function(next) { const targetStoreId = this.getOptions().targetStoreId; if (targetStoreId) { this.populate({ path: "menuItem.product", select: { "storeId.$": 1 }, match: { "storeId.store": targetStoreId } }); } next(); });
补充说明
你之前硬编码"62a811d1af67f5415770f297"能生效,是因为该值是固定的,无需依赖文档字段;但动态关联文档字段时,必须等到查询拿到文档实例后才能获取对应值,或者提前将参数传入查询中。
内容的提问来源于stack exchange,提问作者Jhon Paul
相关产品推荐
相关产品推荐

