如何在MongoDB中随机选取覆盖全难度等级的指定数量文档
MongoDB 按难度等级随机选取文档(覆盖1-10所有难度)
针对你需要随机选取10或20个文档、且必须包含难度等级1到10各至少一个的需求,以下是两种场景的具体实现方案:
场景1:选取恰好10个文档(每个难度等级各1个)
通过聚合管道按难度分组,每组随机抽取1个文档,确保覆盖所有难度:
db.collection.aggregate([ // 可选:过滤出难度在1-10范围内的文档,避免无效数据干扰 { $match: { "Difficulty Level": { $gte: 1, $lte: 10 } } }, // 按难度等级分组,收集每个等级的全部文档 { $group: { _id: "$Difficulty Level", docs: { $push: "$$ROOT" } } }, // 每个难度等级随机选取1个文档 { $project: { randomDoc: { $sample: { input: "$docs", size: 1 } } } }, // 展开单个文档的数组结构 { $unwind: "$randomDoc" }, // 恢复原文档的完整结构 { $replaceRoot: { newRoot: "$randomDoc" } } ])
场景2:选取20个文档(每个难度等级至少1个,剩余10个随机补充)
分两步实现:先获取覆盖所有难度的10个必选文档,再随机补充10个文档,可选去重避免重复:
db.collection.aggregate([ { $match: { "Difficulty Level": { $gte: 1, $lte: 10 } } }, // 同时执行两个聚合分支:获取必选文档和补充文档 { $facet: { requiredDocs: [ { $group: { _id: "$Difficulty Level", docs: { $push: "$$ROOT" } } }, { $project: { randomDoc: { $sample: { input: "$docs", size: 1 } } } }, { $unwind: "$randomDoc" }, { $replaceRoot: { newRoot: "$randomDoc" } } ], extraDocs: [ { $sample: { size: 10 } } // 从所有文档中随机选10个补充 ] } }, // 合并必选文档和补充文档 { $project: { combined: { $concatArrays: ["$requiredDocs", "$extraDocs"] } } }, { $unwind: "$combined" }, // 可选:按文档ID去重,避免同一个文档被重复选中 { $group: { _id: "$combined._id", doc: { $first: "$combined" } } }, { $replaceRoot: { newRoot: "$doc" } }, // 可选:如果去重后数量不足20,重新抽取20个(概率极低,仅针对小集合) // { $sample: { size: 20 } } ])
备选方案(文档数量充足时)
如果每个难度等级的文档数量足够,可以直接每个等级随机选2个,刚好凑够20个:
db.collection.aggregate([ { $match: { "Difficulty Level": { $gte: 1, $lte: 10 } } }, { $group: { _id: "$Difficulty Level", docs: { $push: "$$ROOT" } } }, { $project: { randomDocs: { $sample: { input: "$docs", size: 2 } } } }, { $unwind: "$randomDocs" }, { $replaceRoot: { newRoot: "$randomDocs" } } ])
内容的提问来源于stack exchange,提问作者Brijesh Savaliya
相关产品推荐
相关产品推荐

