如何在Prisma中基于查询结果过滤关联数据(MongoDB)
在Prisma(MongoDB)中基于父文档字段过滤关联查询的方案
方案1:使用MongoDB $expr表达式(推荐)
由于你使用的是MongoDB,Prisma支持通过$expr引用父文档的字段,只需将getInterval的逻辑转换为MongoDB原生聚合操作符,就能在数据库层面完成关联过滤。
假设你的getInterval是根据interval字段计算对应时间范围(比如按天/月/季度截断日期),可以用MongoDB的$dateTrunc、$dateAdd等操作符实现等价逻辑。示例代码如下:
prisma.card.findMany({ include: { user: true, project: true, transaction: { where: { $expr: { $and: [ // 根据card的interval字段截断当前日期,得到周期起始 { $gte: ["$date_created", { $dateTrunc: { date: new Date(), unit: "$interval" } }] }, // 计算周期结束时间(下一个周期的起始) { $lte: ["$date_created", { $dateAdd: { startDate: { $dateTrunc: { date: new Date(), unit: "$interval" } }, amount: 1, unit: "$interval" } }] } ] } }, }, snapshots: true, }, })
你需要根据getInterval的实际逻辑调整MongoDB操作符,确保和原函数的时间范围计算一致。
方案2:客户端层面二次查询
如果getInterval逻辑过于复杂,无法直接转换为MongoDB操作符,可以先查询所有Card数据,再对每个Card单独过滤关联的Transactions:
// 1. 查询所有Card及基础关联数据 const cards = await prisma.card.findMany({ include: { user: true, project: true, snapshots: true, }, }); // 2. 遍历每个Card,查询符合条件的Transactions const cardsWithFilteredTransactions = await Promise.all( cards.map(async (card) => { const intervalRange = getInterval(card.interval); const transactions = await prisma.transaction.findMany({ where: { cardId: card.id, // 替换为你实际的关联字段 date_created: { gte: intervalRange.start, lte: intervalRange.end, }, }, }); return { ...card, transactions }; }) );
注意:这种方式会产生多轮数据库请求,Card数量较多时可能影响性能,适合小数据量场景。
内容的提问来源于stack exchange,提问作者Jeferson Costa
相关产品推荐
相关产品推荐

