我会去规范化一点,并为被喜欢的对象添加一个“喜欢”计数器字段。当对象被喜欢时增加它,当对象不喜欢时减少它。
db.test.insert({
stuff: "likable stuff",
likes: 7
})
然后我还会有另一个字段来表示对象所在的存储桶,因为喜欢。因此,例如,对象开始时将此字段设置为“普通”,在某人获得 10 个赞后,他们将成为“精英”。(或任何你想要的)当他们达到那个阈值时更新它。这里的想法是,在写入方面进行工作将使读取变得更加容易。
db.test.insert({
stuff: "likable stuff",
likes: 7,
status: "ordinary/elite",
})
好的,现在选择您根据点赞数定义的组中的对象集很容易,对吧? db.collection.find({ status: 'elite' })
要在这些集合中随机选择文档,您可以随机跳过给定数量的记录,但这会导致糟糕的性能并且无法扩展。
但是,您可以使用一个技巧,将随机生成的数字存储在文档本身中。
让我们将其中一个人插入测试数据库并检查一下
db.test.insert({
stuff: "likable stuff",
likes: 7,
status: "ordinary/elite",
random: Math.random()
})
现在让我们看一下文档:
{
stuff: "likable stuff",
likes: 7,
status: "ordinary/elite",
random: 0.9375813045563468
}
好的,这就是它变得非常酷的地方。执行 findOne() 查询,其中状态:精英和rand_num:$gt { 另一个随机生成的数字 btw 0 和 1 }。
db.collection.find({ status: "elite", random: { "$gt": new_rand_num } })
如果 findOne() 查询未返回结果,请使用 $lt 再次执行此操作,因为您将确保至少在其中一个方向上找到文档。
现在让我们索引状态和随机。
db.collection.ensureIndex({ status: 1, random: 1} })
你怎么看?