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

如何用Prisma Client查询MongoDB子数组并筛选热门商品

如何用Prisma查询MongoDB分类集合时仅保留热门商品

问题背景

我用Prisma作为ORM操作MongoDB,现有如下Schema:

model Category {
  id       String     @id @default(auto()) @map("_id") @db.ObjectId
  name     String     // 补充:原Schema遗漏该字段,匹配实际数据结构
  products Product[]
}

type Product {
  name    String
  popular Boolean
}

MongoDB分类集合的示例数据:

const category = [
  {
    name: "Juice",
    products: [
      { name: "Mojito", popular: true },
      { name: "Lemon mint", popular: false },
    ],
  },
  {
    name: "Coffee",
    products: [
      { name: "Caramel", popular: true },
      { name: " mint", popular: false },
    ],
  }
];

我需要查询分类集合,仅保留每个分类下popular为true的商品,期望结果:

[
  {
    name: "Juice",
    products: [{ name: "Mojito", popular: true }],
  },
  {
    name: "Coffee",
    products: [{ name: "Caramel", popular: true }],
  },
];

我尝试用where子句的some操作符查询:

const categoriesWithPopularProduct = db.category.findMany({
  where: {
    products: {
      some: {
        popular: { equals: true },
      },
    },
  },
});

但这个查询返回的是分类下的所有商品,而非仅热门商品,请问该如何实现需求?

解决方案

你之前的where.some仅用于筛选符合条件的分类(即包含至少一个热门商品的分类),但不会修改分类下的products数组内容。要实现过滤数组内的元素,需要结合Prisma的select和MongoDB的聚合表达式$filter:

方法1:使用findMany配合select中的$filter

const categoriesWithPopularProduct = await db.category.findMany({
  select: {
    name: true,
    products: {
      $filter: {
        input: "$products",
        cond: { $eq: ["$$this.popular", true] }
      }
    }
  },
  where: {
    // 保留存在热门商品的分类,避免返回products为空的分类
    products: { some: { popular: true } }
  }
});

方法2:使用aggregateRaw执行MongoDB原生聚合管道

如果需要更复杂的操作,也可以直接用原生聚合管道:

const categoriesWithPopularProduct = await db.category.aggregateRaw({
  pipeline: [
    // 过滤每个分类的products数组,仅保留热门商品
    {
      $addFields: {
        products: {
          $filter: {
            input: "$products",
            cond: { $eq: ["$$this.popular", true] }
          }
        }
      }
    },
    // 过滤掉products为空的分类
    { $match: { products: { $ne: [] } } }
  ]
});

原理说明

  • $filter是MongoDB的聚合操作符,用于遍历数组并根据条件筛选元素,$$this代表数组中的当前元素。
  • 搭配where.some(或聚合管道中的$match)可以确保最终结果只包含有热门商品的分类,不会出现products为空数组的条目。

内容的提问来源于stack exchange,提问作者Jay

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 00:57:25