我在MongoDB中有一个包含约600,000个文档的集合。其中,正好一半的字段设置为0,而其他字段设置为1.当我尝试使用聚合管道中的sample操作从此集合中获取随机样本时(通过PyMongo) ,它严重偏向1值。
在25,000个记录样本中,可能有300-400条记录,其中字段为0,然后是24,000多条记录,其中有关字段为1.
如果初始集合是平均分配的,那么为什么使用$sample
返回的结果具有如此大不相同的分布,以及如何从集合中获取代表性样本?
这是我用于查询的PyMongo行:
cursor = foo_database.bar_collection.aggregate( [ { "$sample": { "size": 25000} } ])
答案 0 :(得分:2)
从MongoDB 3.4.9开始,您观察到偏见的部分原因是$sample
几乎完全依赖于存储引擎的随机游标实现(参见SERVER-19183 })。这样做是为了在集合包含大量数据时$sample
可以执行。但是,由于存储引擎使用B树类型实现以排序顺序存储文档,因此并不总是能够创建真正随机的结果。
目前有两项针对更好$sample
机制的功能请求,即SERVER-22069和SERVER-22068。
话虽如此,如果您需要真正无偏见的数据样本,那么滚动您自己的$sample
类解决方案可能是此时继续进行的最佳方式。类似的东西:
_id
的列表。_id
获取所有相关文档,根据您想要的样本大小,这将是合理的,因为_id
始终被编入索引。