云开发按照幸运值进行随机抽奖实现思路
发布于 4 年前 作者 pingren 2793 次浏览 来自 分享

昨天遇到一个需求:一个抽奖活动,参与的用户都有一个幸运值,幸运值是可以通过任务增加的,幸运值越高,中奖率越大(幸运用户5位)。

期初思路:用 sample 随机抽取幸运用户,sample 只能是随机筛选,没办法敢于,显然是不行的

中期思路:可不可以用聚合,在聚合阶段利用随机数乘以原始幸运值生成一个临时的幸运值,然后根据临时幸运值排序获取前5条数据,这样似乎可行,也没毛病。理论可行,开撸

const result = await db.collection('test_data')
    .aggregate()
    .project({
      luck_num1,
      name1,
      temp_luck_num: $.multiply([Math.random(), '$luck_num'])
    })
    .sort({
      temp_luck_num-1,
    })
    .limit(5)
    .end()


但是,结果却跟预想的有所偏差,经过分析,原因如下:在聚合计算阶段  temp_luck_num: $.multiply([Math.random(), '$luck_num'])中Math.random() 已经得出一个常数,也就是说效果跟 temp_luck_num: $.multiply([0.2365, '$luck_num'])是一样的,仍然无法达到随机的目的,temp_luck_num: $.multiply([para, '$luck_num']),初需要一个变量随机数,而此处的Math.random() 已经是是一个确切的值,好像陷入了一个死胡同。

最终解决方案:既然这个地方无法利用随机数进行计算,从数据源头解决是否可以?顺着这个思路终于想到一个办法:当用户参与抽奖的时候添加该用户抽奖信息时,直接生成一个随机数(temp_random),记录到用户抽奖信息中,开奖时利用 temp_random 及 luck_num 计算出临时幸运值,然后再排序获取。

 const result = await db.collection('test_data')
    .aggregate()
    .project({
      luck_num: 1,
      name: 1,
      temp_luck_num: $.multiply(["$temp_random"'$luck_num'])
    })
    .sort({
      temp_luck_num: -1,
    })
    .limit(5)
    .end()


如有更好的解决办法,请不吝赐教

回到顶部