乐闻世界logo
搜索文章和话题

Mongoose 如何随机查询记录?

4 个月前提问
3 个月前修改
浏览次数19

1个答案

1

在Mongoose中,如果想要随机查询记录,可以采取一些策略。以下是一个常见的策略示例:

  1. 使用 $sample 聚合管道操作符: MongoDB 提供了一个 $sample 的聚合管道操作符,可以用来随机选择集合中的一定数量的文档。在Mongoose中,我们可以如下使用:

    javascript
    // 假设我们有一个叫做Model的模型 Model.aggregate([ { $sample: { size: 1 } } ]) .then(doc => { // 你得到的doc将是一个包含一个随机文档的数组 console.log(doc); }) .catch(err => { console.error(err); });

    这个查询会从Model代表的集合中随机选取一个文档。

  2. 查询总数并使用 $skip: 如果你的数据库版本不支持 $sample 操作符,或者你需要在查询中执行更多的操作,还可以先查询获取集合的总数,然后生成一个随机数作为 $skip 的参数来跳过随机数目的文档。

    javascript
    Model.count().exec(function (err, count) { if (err) { console.log(err); } else { var random = Math.floor(Math.random() * count); Model.findOne().skip(random).exec( function (err, result) { // result 是随机的单个文档 console.log(result); } ); } });

    这个方法首先计算集合中文档的数量,然后生成一个随机的索引,接着使用.findOne().skip(random)来获取随机的文档。

  3. 使用 _id$gte$lte: 另一种方法是基于_id字段,该字段通常由MongoDB随机生成。你可以随机生成一个和_id相同格式的值,然后查询第一个大于或等于($gte)或小于或等于($lte)这个随机值的文档。

    javascript
    var randomId = new mongoose.Types.ObjectId(); Model.findOne({ _id: { $gte: randomId } }).exec(function (err, doc) { // 如果没有找到,则可能是随机的_id大于集合中的任何_id,因此再次尝试使用$lte if (doc) { console.log(doc); } else { Model.findOne({ _id: { $lte: randomId } }).exec(function (err, doc) { console.log(doc); }); } });

    这个方法的效率取决于_id的分布情况,对于小型集合可能不够均匀。

请注意,对于大型集合,某些方法(如使用$skip)可能会引起性能问题,因为MongoDB需要遍历skip的所有文档。对于大型集合,使用$sample操作符通常是最佳选择。

2024年6月29日 12:07 回复

你的答案