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

如何在Express路由中实现从数据库调取12-15个不重复随机商品

实现方案

你可以直接使用MongoDB原生的$sample聚合操作符实现需求,该操作符可以从匹配的数据集里随机返回指定数量的不重复文档,性能最优,适配绝大多数场景:

方案1:MongoDB $sample 聚合(推荐)

router.get("/alw", function(req, res){
    // 生成12~15之间的随机整数,包含边界值
    const fetchCount = Math.floor(Math.random() * 4) + 12;
    Product.aggregate([
        // 先过滤分类为alw的商品
        { $match: { category: "alw" } },
        // 随机取出fetchCount个不重复的商品
        { $sample: { size: fetchCount } }
    ], function(err, products){
        if (err){
            console.log(err);
            return res.status(500).send("数据查询失败");
        }
        res.render("products/alw", {products: products});
    });
});

优势:

  • 数据库层面直接完成随机筛选,性能远高于全量查询后再做数据处理,哪怕分类下有数十万条商品也不会有性能问题
  • 原生保证返回的商品无重复,不需要额外写去重逻辑
  • 代码简洁易维护

方案2:全量查询后洗牌(仅适用于分类下商品总数<1000的场景)

如果你使用的MongoDB版本低于3.2不支持$sample,可以全量查询后用Fisher-Yates洗牌算法打乱数组再截取:

router.get("/alw", function(req, res){
    Product.find({"category": "alw"}, function(err, allProduct){
        if (err){
            console.log(err);
            return res.status(500).send("数据查询失败");
        }
        // Fisher-Yates 洗牌算法打乱数组,保证完全随机
        for (let i = allProduct.length - 1; i > 0; i--) {
            const j = Math.floor(Math.random() * (i + 1));
            [allProduct[i], allProduct[j]] = [allProduct[j], allProduct[i]];
        }
        // 生成随机取数数量,兼容分类下商品不足12的边界情况
        const fetchCount = Math.min(Math.floor(Math.random() * 4) + 12, allProduct.length);
        const randomProducts = allProduct.slice(0, fetchCount);
        res.render("products/alw", {products: randomProducts});
    });
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 05:24:05