Ila*_*sda 12 javascript random mongodb mlab restangular
MongoDB是否能够在不进行多次查询的情况下为随机文档提供资金?
例如,我在将所有文档加载到集合中后在JS端实现,这很浪费 - 因此只是想检查一次db查询是否可以做得更好?
我在JS方面采取的路径:
两个主要缺点是我正在加载所有数据 - 或者我进行了多次查询.
任何建议都非常感谢
Dan*_*ick 27
从3.2开始,有一种更简单的方法可以从集合中获取随机的文档样本:
$ sample 3.2版本中的新功能.
从输入中随机选择指定数量的文档.
$ sample阶段具有以下语法:
{ $sample: { size: <positive integer> } }
在这种情况下:
db.products.aggregate([{$sample: {size: 10}}]);
Run Code Online (Sandbox Code Playgroud)
Enr*_*eyo 20
这是很久以前的答案,从那时起,MongoDB已经有了很大的发展.
正如另一个答案所述,MongoDB现在支持从版本3.2开始在聚合框架内进行采样:
你可以这样做的方式是:
db.products.aggregate([{$sample: {size: 5}}]); // You want to get 5 docs
Run Code Online (Sandbox Code Playgroud)
要么:
db.products.aggregate([
{$match: {category:"Electronic Devices"}}, // filter the results
{$sample: {size: 5}} // You want to get 5 docs
]);
Run Code Online (Sandbox Code Playgroud)
(截至2017年11月6日,最新版本为3.4)=>如果不满足以下任何条件:
如果不满足上述任何条件,$ sample将执行集合扫描,然后进行随机排序以选择N个文档.
就像在上一个与$ match的例子中一样
老答复
你总是可以运行:
db.products.find({category:"Electronic Devices"}).skip(Math.random()*YOUR_COLLECTION_SIZE)
Run Code Online (Sandbox Code Playgroud)
但订单不是随机的,你需要两个查询(一个计数来获得YOUR_COLLECTION_SIZE)或估计它有多大(它是大约100条记录,大约1000条,大约10000条...)
您还可以使用随机数向所有文档添加字段,并按该编号查询.这里的缺点是每次运行相同的查询时都会得到相同的结果.要解决此问题,您始终可以使用限制和跳过,甚至可以使用排序.您每次获取记录时都可以更新这些随机数(意味着更多查询).
- 我不知道您是否使用Mongoose,Mondoid或直接使用Mongo驱动程序获取任何特定语言,所以我会写关于mongo shell的所有信息.
因此,您的产品记录将如下所示:
{
_id: ObjectId("..."),
name: "Awesome Product",
category: "Electronic Devices",
}
Run Code Online (Sandbox Code Playgroud)
我建议使用:
{
_id: ObjectId("..."),
name: "Awesome Product",
category: "Electronic Devices",
_random_sample: Math.random()
}
Run Code Online (Sandbox Code Playgroud)
然后你可以这样做:
db.products.find({category:"Electronic Devices",_random_sample:{$gte:Math.random()}})
Run Code Online (Sandbox Code Playgroud)
然后,您可以定期运行,以便定期更新文档的_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)
Run Code Online (Sandbox Code Playgroud)
或者只要你检索一些记录,就可以更新所有记录或只更新一些(取决于你检索的记录数)
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);
}
Run Code Online (Sandbox Code Playgroud)
编辑
意识到
db.products.update(your_query,{$set:{_random_sample::Math.random()}},false,true)
Run Code Online (Sandbox Code Playgroud)
将无法正常工作,因为它将使用相同的随机数更新与您的查询匹配的每个产品.最后一种方法效果更好(在检索时更新一些文档)
| 归档时间: |
|
| 查看次数: |
15962 次 |
| 最近记录: |