MongoDB的$sample是啥?

$sample 是 MongoDB 聚合管道(Aggregation Pipeline)中的一个非常实用的阶段,它的作用是:

从集合中随机抽取指定数量的文档。


✅ 基本语法

js 复制代码
{ $sample: { size: N } }
  • size: 你要随机抽取的文档数量。

📌 示例

假设你有一个 questions 集合,里面有 1000 道题,你想随机抽 5 道用于练习:

js 复制代码
db.questions.aggregate([
  { $sample: { size: 5 } }
])

每次运行都会返回 5 条随机题目,非常适合:

  • 随机组卷
  • 推荐系统(随机推荐几条内容)
  • 抽奖功能
  • 数据抽样分析

🔍 它是怎么实现"随机"的?

MongoDB 并不是真的"完全随机读取每一条",而是使用一种高效的算法:

  • 如果集合小:直接加载所有文档,随机挑选
  • 如果集合大:使用 ** reservoir sampling(蓄水池抽样)** 算法,在不加载全部数据的情况下实现均匀随机

⚡️ 性能很好,即使千万级数据也能快速抽样


🆚 对比:为什么不用 find().limit().skip(Math.random())

你可能会想:我能不能这样做?

js 复制代码
const count = await db.questions.countDocuments();
const randomSkip = Math.floor(Math.random() * count);
db.questions.find().skip(randomSkip).limit(5);

不推荐!原因:

问题 说明
不是真正随机 只是从某个位置往后取,容易重复或偏移
性能差 skip(N) 越大,越慢(要跳过前 N 条)
分布不均 数据增删后,随机性变差

✅ 而 $sample

  • 真正均匀随机
  • 性能稳定
  • 自动优化

🧩 实际应用场景

1. 随机出题(考试系统)
js 复制代码
// 随机抽 10 道单选题
db.questions.aggregate([
  { $match: { type: "single" } },
  { $sample: { size: 10 } }
])
2. 每日推荐(随机推荐 3 篇文章)
js 复制代码
db.articles.aggregate([
  { $match: { status: "published" } },
  { $sample: { size: 3 } }
])
3. 抽奖系统(从参与用户中抽 1 名幸运儿)
js 复制代码
db.participants.aggregate([
  { $sample: { size: 1 } }
])

⚠️ 注意事项

  1. 不能保证绝对唯一:多次调用可能抽到同一条(毕竟是随机)
  2. 适合中小规模抽样size 不宜过大(比如 size: 10000 可能慢)
  3. 不适用于"分页随机" :如果你要做"第一页随机5条,第二页再随机5条",直接用 $sample 每次都行,但无法保证不重复(需要业务层去重)

✅ 最佳实践

js 复制代码
// 安全做法:先过滤,再抽样
db.questions.aggregate([
  { $match: { 
      status: "active", 
      difficulty: "easy" 
  } },
  { $sample: { size: 5 } }
])

这样既高效又精准。


🎯 总结

特性 说明
作用 随机抽取 N 条文档
语法 { $sample: { size: N } }
优点 真随机、性能好、语法简单
适用场景 抽题、推荐、抽奖、数据抽样
替代方案 skip(random) 不推荐

如果你想做一个"每日一题"功能,用 $sample 再合适不过了!

相关推荐
x10n923 分钟前
OceanBase 参数对比工具 附源码
数据库·vscode·oceanbase·腾讯云ai代码助手
RestCloud31 分钟前
如何用ETL做实时风控?从交易日志到告警系统的实现
数据库·数据仓库·kafka·数据安全·etl·数据处理·数据集成
云和恩墨1 小时前
MySQL和PostgreSQL谁更适合AI时代?
数据库
数据猿1 小时前
【金猿人物展】涛思数据创始人、CEO陶建辉:实现AI时代时序数据库向“数据平台”的转型
大数据·数据库·人工智能·时序数据库·涛思数据
当代红领巾1 小时前
Oracle 表空间扩容
数据库·oracle
小光学长1 小时前
基于ssm的美妆产品推荐系统rah0h134(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
java·数据库·spring
_果果然2 小时前
数据库、表、字段:理解MySQL的三层结构
数据库·mysql
Leon-Ning Liu2 小时前
Oracle 19c RAC ASM 密码文件恢复方方案二:基于密码文件备份还原
数据库·oracle
间彧2 小时前
TiDB详解与应用实战:分布式数据库的核心原理与最佳实践
数据库
半夏知半秋2 小时前
Elasticsearch Query DSL 指令整理
大数据·数据库·笔记·学习·elasticsearch·搜索引擎·全文检索