You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 17:48:08