我有一个看起来像这样的集合:
[
{
"id": 1,
"tier": 0
},
{
"id": 2,
"tier": 1
},
{
"id": 3
"tier": 2
},
{
"id": 4,
"tier": 0
}
]
是否有一种标准的方法来选择n个元素,其中选择最低层元素的概率为p,下一个最低层为(1-p)*p,以此类推,使用标准的随机选择元素?
因此,例如,如果最可能的事情发生,我运行查询上面的例子与n = 2和任何p> .5(我认为这将永远是真的),那么我会回到[{"id": 1, ...}, {"id": 4}]
;当n = 3时,则[{"id": 4}, {"id": 1}, {"id": 2}]
,以此类推
。下面是一些伪python代码,给出一个像objs:
这样的字典def f(objs, p, n):
# get eligible tiers
tiers_set = set()
for o in objs:
eligible_tiers.add(o["tier"])
tiers_list = sorted(list(tiers_set))
# get the tier for each index of results
tiers = []
while len(tiers) < min(n, len(obis)):
tiers.append(select_random_with_initial_p(eligible_tiers, p))
# get res
res = []
for tier in tiers:
res.append(select_standard_random_in_tier(objs, tier)
return res
首先,在集合上启用地理空间索引:
db.docs.ensureIndex( { random_point: '2d' } )
创建一组在x轴上随机点的文档:
for ( i = 0; i < 10; ++i ) {
db.docs.insert( { key: i, random_point: [Math.random(), 0] } );
}
然后你可以像这样从集合中得到一个随机的文档:
db.docs.findOne( { random_point : { $near : [Math.random(), 0] } } )
或者您可以检索离随机点最近的几个文档:
db.docs.find( { random_point : { $near : [Math.random(), 0] } } ).limit( 4 )
这只需要一个查询,没有null检查,加上代码干净,简单和灵活。您甚至可以使用地理点的y轴向您的查询添加第二个随机性维度。
要进行自定义随机选择,您可以更改[Math.random(), 0]
部分,使其最适合您的随机分布
来源:MongoDB的随机记录