gpt4 book ai didi

javascript - MongoDB:如何在 100 个集合中找到 10 个随机文档?

转载 作者:IT老高 更新时间:2023-10-28 13:14:25 30 4
gpt4 key购买 nike

MongoDB 是否能够在不进行多次查询的情况下资助大量随机文档?

例如我在加载集合中的所有文档后在 JS 端实现,这很浪费 - 因此只想检查是否可以通过一个 db 查询更好地完成?

我在JS这边走的路:

  • 获取所有数据
  • 制作一个 ID 数组
  • 随机播放 ID 数组(随机顺序)
  • 将数组拼接到所需文档的数量
  • 通过在前两次操作后留下的 ID 选择文档来创建一个文档列表,从整个集合中一个一个地选择它们

两个主要缺点是我正在加载所有数据 - 或者我进行了多个查询。

非常感谢任何建议

最佳答案

很久以前就回答了这个问题,从那时起,MongoDB 有了很大的发展。

正如另一个答案中所发布的,MongoDB 现在支持 sampling within the Aggregation Framework从 3.2 版开始:

你可以这样做:

db.products.aggregate([{$sample: {size: 5}}]); // You want to get 5 docs

或者:

db.products.aggregate([
{$match: {category:"Electronic Devices"}}, // filter the results
{$sample: {size: 5}} // You want to get 5 docs
]);

但是,有 some warnings关于 $sample 运算符:

(截至 2017 年 11 月 6 日,最新版本为 3.4)=> 如果不满足任何条件:

  • $sample 是流水线的第一阶段
  • N 小于集合中文档总数的 5%
  • 该集合包含 100 多个文档

If any of the above conditions are NOT met, $sample performs a collection scan followed by a random sort to select N documents.

就像上一个例子中的 $match

老答案

你总是可以跑的:

db.products.find({category:"Electronic Devices"}).skip(Math.random()*YOUR_COLLECTION_SIZE)

但顺序不会是随机的,您将需要两次查询(一次计数以获取 YOUR_COLLECTION_SIZE)或估计它有多大(大约 100 条记录,大约 1000 条,大约 10000 条......)

您还可以使用随机数向所有文档添加一个字段并按该数字进行查询。这里的缺点是每次运行相同的查询时都会得到相同的结果。要解决此问题,您始终可以使用限制和跳过甚至排序。您也可以在每次获取记录时更新这些随机数(意味着更多查询)。

--我不知道你是在使用Mongoose、Mondoid还是直接使用Mongo Driver来支持任何特定语言,所以我会写关于mongo shell的所有内容。

因此,假设您的产品记录如下所示:

{
_id: ObjectId("..."),
name: "Awesome Product",
category: "Electronic Devices",
}

我建议使用:

{
_id: ObjectId("..."),
name: "Awesome Product",
category: "Electronic Devices",
_random_sample: Math.random()
}

那么你可以这样做:

db.products.find({category:"Electronic Devices",_random_sample:{$gte:Math.random()}})

然后,您可以定期运行,以便定期更新文档的 _random_sample 字段:

var your_query = {} //it would impact in your performance if there are a lot of records
your_query = {category: "Electronic Devices"} //Update
//upsert = false, multi = true
db.products.update(your_query,{$set:{_random_sample::Math.random()}},false,true)

或者只是每当您检索一些记录时,您可以更新所有记录或仅更新一些记录(取决于您检索到的记录数)

for(var i = 0; i < records.length; i++){
var query = {_id: records[i]._id};
//upsert = false, multi = false
db.products.update(query,{$set:{_random_sample::Math.random()}},false,false);
}

编辑

请注意

db.products.update(your_query,{$set:{_random_sample::Math.random()}},false,true)

不会很好地工作,因为它会使用相同的随机数更新与您的查询匹配的所有产品。最后一种方法效果更好(在检索某些文档时更新它们)

关于javascript - MongoDB:如何在 100 个集合中找到 10 个随机文档?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24806721/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com