MongoDB聚合运算符:$rand
文章目录
- [MongoDB聚合运算符:rand](#MongoDB聚合运算符:rand)
$rand
聚合运算符用于返回一个0~1之间的随机浮点数。
语法
js
{ $rand: {} }
$rand
运算符不需要任何参数。每次调用$rand
都会返回一个小数点后最多17位数字的浮点数值。尾数0会被去掉,因此实际位数可能会有所不同。
举例
生成随机数据点
使用下面的脚本创建donors
集合包含了慈善捐款的信息:
js
db.donors.insertMany(
[
{ donorId: 1000, amount: 0, frequency: 1 },
{ donorId: 1001, amount: 0, frequency: 2 },
{ donorId: 1002, amount: 0, frequency: 1 },
{ donorId: 1003, amount: 0, frequency: 2 },
{ donorId: 1004, amount: 0, frequency: 1 }
]
)
下面的聚合用随机捐赠金额更新每个文档:
js
db.donors.aggregate(
[
{ $set: { amount: { $multiply: [ { $rand: {} }, 100 ] } } },
{ $set: { amount: { $floor: "$amount" } } },
{ $merge: "donors" }
]
)
第一个$set
阶段更新amount
字段,使用$rand
产生0和1之间的初始值,然后使用$multiply
乘以100。
第二个$set
阶段,使用$floor
运算符去除amount
的小数部分,只留下整数值。
最后,使用$merge
将前一步骤生成的amount
字段值更新到donors
集合的每个文档。
可以使用一个$project
阶段来查看结果:
js
db.donors.aggregate(
[
{ $project: {_id: 0, donorId: 1, amount: 1 } }
]
)
投影显示缩放后的值为0到99的随机值:
json
{ "donorId" : 1000, "amount" : 27 }
{ "donorId" : 1001, "amount" : 10 }
{ "donorId" : 1002, "amount" : 88 }
{ "donorId" : 1003, "amount" : 73 }
{ "donorId" : 1004, "amount" : 5 }
从集合中随机选择条目
可以在聚合管道中使用$rand
从集合中选择随机文档,使用下面的脚本创建voters
集合:
js
db.voters.insertMany(
[
{ name: "Archibald", voterId: 4321, district: 3, registered: true },
{ name: "Beckham", voterId: 4331, district: 3, registered: true },
{ name: "Carolin", voterId: 5321, district: 4, registered: true },
{ name: "Debarge", voterId: 4343, district: 3, registered: false },
{ name: "Eckhard", voterId: 4161, district: 3, registered: false },
{ name: "Faberge", voterId: 4300, district: 1, registered: true },
{ name: "Grimwald", voterId: 4111, district: 3, registered: true },
{ name: "Humphrey", voterId: 2021, district: 3, registered: true },
{ name: "Idelfon", voterId: 1021, district: 4, registered: true },
{ name: "Justo", voterId: 9891, district: 3, registered: false }
]
)
假如要选择第3区大约一半的选民进行投票,如下面的聚合:
js
db.voters.aggregate(
[
{ $match: { district: 3 } },
{ $match: { $expr: { $lt: [0.5, {$rand: {} } ] } } },
{ $project: { _id: 0, name: 1, registered: 1 } }
]
)
第一个$match
阶段对所有文档进行筛选,挑选出第三区的选民。
第二个$match
阶段在匹配表达式中使用$rand
进一步完善选择。$rand
对每个文档产生一个介于0到1的值,$lt
小于0.5意味着$expr
有一半的文档返回true
。
在$project
阶段,筛选后的文档输出name
和registered
字段,有7个选民在第三区,大约占全部的一半。
json
{ "name" : "Archibald", "registered" : true }
{ "name" : "Debarge", "registered" : false }
{ "name" : "Humphrey", "registered" : true }