如何在Mongoose中查询嵌套文档里状态为active的订阅记录?
获取Mongoose嵌套文档中特定状态的订阅
嘿,看起来你已经搭好了Customer和Subscription的模型,现在想筛选出某个客户的active状态订阅对吧?我给你几个实用的方案,你可以根据场景选:
方案1:先查客户,再在代码里过滤(简单易上手)
如果你客户的订阅数量不多,直接先拿到完整的客户文档,然后用JS数组方法过滤就行,代码改动最小:
let customer = await CustomerModel.findOne({ telegram_id: ctx.chat.id }); // 过滤出status为active的订阅 const activeSubscriptions = customer.subscriptions.filter(sub => sub.status === 'active'); console.log(activeSubscriptions);
这种方法好处是不用写复杂的数据库查询,适合快速实现。
方案2:用MongoDB聚合管道在数据库层面过滤(高效,适合大数据量)
如果想让数据库直接返回过滤后的结果,减少数据传输,可以用聚合管道的$match和$project结合$filter操作符:
const result = await CustomerModel.aggregate([ // 第一步:匹配到目标客户 { $match: { telegram_id: ctx.chat.id } }, // 第二步:投影出需要的字段,并用$filter过滤subscriptions { $project: { stripe_id: 1, email: 1, activeSubscriptions: { $filter: { input: "$subscriptions", as: "sub", cond: { $eq: ["$$sub.status", "active"] } } } } } ]); // 聚合返回的是数组,取第一个元素 const activeSubscriptions = result[0]?.activeSubscriptions || [];
这种方法在数据库端完成过滤,性能更好,尤其是当订阅数量很多的时候。
方案3:用Mongoose查询的投影语法(简洁写法)
MongoDB 3.2及以上版本支持在投影里直接用$filter,你也可以把它写在findOne的投影参数里:
let customer = await CustomerModel.findOne( { telegram_id: ctx.chat.id }, { stripe_id: 1, email: 1, activeSubscriptions: { $filter: { input: "$subscriptions", as: "sub", cond: { $eq: ["$$sub.status", "active"] } } } } ); const activeSubscriptions = customer.activeSubscriptions || [];
这个写法和聚合管道效果类似,但更简洁,适合只需要单个文档的场景。
需要注意的是,$elemMatch虽然也能用来匹配嵌套文档,但它只会返回第一个符合条件的订阅,所以不适合你需要所有active订阅的需求,别用错啦!
内容的提问来源于stack exchange,提问作者sfarzoso
相关产品推荐
相关产品推荐

