从MongoDB集合中返回随机文档样本的3种方法
如果需要从集合中返回一小部分随机文档示例,可以使用聚合管道尝试以下三种方法。
舞台$sample
聚合管道阶段专门设计用于随机选择指定数量的文档。[$sample](https://database.guide/mongodb-sample/ "MongoDB $sample")
使用 时,可以指定要在字段中返回的文档数。$sample``size
假设我们有以下集合,名为:pets
{ “_id” : 1, “name” : “Wag”, “type” : “Dog”, “weight” : 20 } { “_id” : 2, “name” : “Bark”, “type” : “Dog”, “weight” : 10 } { “_id” : 3, “name” : “Meow”, “type” : “Cat”, “weight” : 7 } { “_id” : 4, “name” : “Scratch”, “type” : “Cat”, “weight” : 8 } { “_id” : 5, “name” : “Bruce”, “type” : “Bat”, “weight” : 3 } { “_id” : 6, “name” : “Hop”, “type” : “Kangaroo”, “weight” : 130 } { “_id” : 7, “name” : “Punch”, “type” : “Gorilla”, “weight” : 300 } { “_id” : 8, “name” : “Snap”, “type” : “Crocodile”, “weight” : 400 } { “_id” : 9, “name” : “Flutter”, “type” : “Hummingbird”, “weight” : 1 }
我们可以像这样随机抓取这些文档的样本:$sample
db.pets.aggregate( [ { $sample: { size: 3 } } ] )
输出:
{ "_id" : 1, "name" : "Wag", "type" : "Dog", "weight" : 20 }
{ "_id" : 5, "name" : "Bruce", "type" : "Bat", "weight" : 3 }
{ "_id" : 3, "name" : "Meow", "type" : "Cat", "weight" : 7 }在本例中,我指定了返回三个文档。{ size: 3 }
这里再次使用不同的样本大小:
db.pets.aggregate(
[
{
$sample: { size: 5 }
}
]
)
输出:
{ "_id" : 6, "name" : "Hop", "type" : "Kangaroo", "weight" : 130 }
{ "_id" : 5, "name" : "Bruce", "type" : "Bat", "weight" : 3 }
{ "_id" : 8, "name" : "Snap", "type" : "Crocodile", "weight" : 400 }
{ "_id" : 7, "name" : "Punch", "type" : "Gorilla", "weight" : 300 }
{ "_id" : 4, "name" : "Scratch", "type" : "Cat", "weight" : 8 }阶段以两种方式之一工作,具体取决于集合中的文档数、相对于集合中文档数的样本大小及其在管道中的位置。请参阅 MongoDB $sample 了解其工作原理。$sample
该阶段也可能在其结果集中多次返回同一文档。$sample
运营商$rand
该运算符是在 MongoDB 4.4.2 中引入的,其目的是在每次调用时返回 0 到 1 之间的随机浮点数。$rand
因此,我们可以在阶段中与其他运算符结合使用,例如 和 返回文档的随机样本。$match``$expr``$lt
例:
db.pets.aggregate(
[
{
$match:
{
$expr:
{
$lt: [ 0.5, { $rand: {} } ]
}
}
}
]
)
输出:
{ "_id" : 3, "name" : "Meow", "type" : "Cat", "weight" : 7 }
{ "_id" : 4, "name" : "Scratch", "type" : "Cat", "weight" : 8 }
{ "_id" : 6, "name" : "Hop", "type" : "Kangaroo", "weight" : 130 }
{ "_id" : 9, "name" : "Flutter", "type" : "Hummingbird", "weight" : 1 }此方法的结果集与该方法不同,因为它不返回固定数量的文档。使用此方法返回的文档数可能会有所不同。$sample
例如,当我多次运行相同的代码时,会发生什么情况。
结果集 2:
{ “_id” : 1, “name” : “Wag”, “type” : “Dog”, “weight” : 20 } { “_id” : 7, “name” : “Punch”, “type” : “Gorilla”, “weight” : 300 } { “_id” : 8, “name” : “Snap”, “type” : “Crocodile”, “weight” : 400 }
结果集 3:
{ “_id” : 2, “name” : “Bark”, “type” : “Dog”, “weight” : 10 } { “_id” : 4, “name” : “Scratch”, “type” : “Cat”, “weight” : 8 } { “_id” : 9, “name” : “Flutter”, “type” : “Hummingbird”, “weight” : 1 }
结果集 4:
{ “_id” : 1, “name” : “Wag”, “type” : “Dog”, “weight” : 20 } { “_id” : 3, “name” : “Meow”, “type” : “Cat”, “weight” : 7 } { “_id” : 6, “name” : “Hop”, “type” : “Kangaroo”, “weight” : 130 } { “_id” : 8, “name” : “Snap”, “type” : “Crocodile”, “weight” : 400 }
结果集 5:
{ “_id” : 1, “name” : “Wag”, “type” : “Dog”, “weight” : 20 } { “_id” : 4, “name” : “Scratch”, “type” : “Cat”, “weight” : 8 } { “_id” : 7, “name” : “Punch”, “type” : “Gorilla”, “weight” : 300 } { “_id” : 8, “name” : “Snap”, “type” : “Crocodile”, “weight” : 400 } { “_id” : 9, “name” : “Flutter”, “type” : “Hummingbird”, “weight” : 1 }
运营商$sampleRate
在MongoDB 4.4.2中引入的运算符提供了一种与前面的示例相同的更简洁的方法。$sampleRate
使用 时,提供采样率作为介于 和 之间的浮点数。选择过程使用均匀随机分布,您提供的采样率表示给定文档在通过管道时被选中的概率。$sampleRate``0``1
例:
db.pets.aggregate(
[
{
$match: { $sampleRate: 0.5 }
}
]
)
输出:
{ "_id" : 1, "name" : "Wag", "type" : "Dog", "weight" : 20 }
{ "_id" : 2, "name" : "Bark", "type" : "Dog", "weight" : 10 }
{ "_id" : 5, "name" : "Bruce", "type" : "Bat", "weight" : 3 }
{ "_id" : 6, "name" : "Hop", "type" : "Kangaroo", "weight" : 130 }
{ "_id" : 7, "name" : "Punch", "type" : "Gorilla", "weight" : 300 }
{ "_id" : 8, "name" : "Snap", "type" : "Crocodile", "weight" : 400 }然后再次运行它:
{ “_id” : 3, “name” : “Meow”, “type” : “Cat”, “weight” : 7 } { “_id” : 4, “name” : “Scratch”, “type” : “Cat”, “weight” : 8 } { “_id” : 7, “name” : “Punch”, “type” : “Gorilla”, “weight” : 300 } { “_id” : 8, “name” : “Snap”, “type” : “Crocodile”, “weight” : 400 } { “_id” : 9, “name” : “Flutter”, “type” : “Hummingbird”, “weight” : 1 }
再说一遍:
{ “_id” : 1, “name” : “Wag”, “type” : “Dog”, “weight” : 20 } { “_id” : 2, “name” : “Bark”, “type” : “Dog”, “weight” : 10 } { “_id” : 3, “name” : “Meow”, “type” : “Cat”, “weight” : 7 } { “_id” : 8, “name” : “Snap”, “type” : “Crocodile”, “weight” : 400 }