从mongodb集合中检索唯一的随机项?

时间:2010-12-19 10:42:02

标签: mongodb random

我运行一个IRC机器人,我有一个函数,从我的Mongodb集合中使用Math.random返回1个随机URL。

我想重构它以返回x个唯一的项目,并且对于url获取命令.getlinks的每次后续调用,我希望它保持一切唯一,这样用户就不会看到相同的链接除非已经返回所有可能的链接。

我可以使用一些算法或本机mongodb函数吗?

以下是一个示例场景:

我在该系列中共有9条记录。他们有_idurl字段。

user a: .getlinks()
bot returns: http://unique-link-1, http://unique-link-2, http://unique-link-3, http://unique-link-4

user a: .getlinks()
bot returns: http://unique-link-5, http://unique-link-6, http://unique-link-7, http://unique-link-8

user a: .getlinks()
bot returns: http://unique-link-9, http://unique-link-6, http://unique-link-1, http://unique-link-3

背景资料:

  • 总共有大约200个链接。我估计到明年年底将增加到5000个链接。

目前我能想到的唯一一件事就是保留所有退回物品的数组,并立即从集合中抓取所有物品并随机获取4次,并确保它是唯一的并且尚未显示。< / p>

var shown = [], amountToReturn = 4;
function getLinks() {
   var items = links.find(), returned = [];
   for ( var i = 0; i<amountToReturn; i++ ) {
      var rand = randItem( items );
      if ( shown.indexOf( rand.url ) == -1 && shown.length < items.length ) ) {
         returned.push( rand.url );
      }
   }
   message.say( returned.join(',') );
}

2 个答案:

答案 0 :(得分:2)

您应该在 从集合中获取随机商品 的许多可能选项......

http://jira.mongodb.org/browse/SERVER-533

此处记录了另一种有用的方法......

http://cookbook.mongodb.org/patterns/random-attribute/

上述方法基本上使用Math.random()

在文档上创建一个新的键/值
> db.docs.drop()
> db.docs.save( { key : 1, ..., random : Math.random() } )
> db.docs.save( { key : 1, ..., random : Math.random() } )
> db.docs.save( { key : 2, ..., random : Math.random() } )
... many more insertions with 'key : 2' ...
> db.docs.save( { key : 2, ..., random : Math.random() } )
...

答案 1 :(得分:1)

Get random records form mongodb via map/reduce

// map
function() { 
    emit(0, {k: this, v: Math.random()}) 
}

// reduce
function(k, v) {
  var a = []
  v.forEach(function(x) {
    a = a.concat(x.a ? x.a : x)
  })
  return {a:a.sort(function(a, b) {
    return a.v - b.v;
  }).slice(0, 3 /*how many records you want*/)}; 
}

// finalize
function(k, v) {
  return v.a.map(function(x) {
    return x.k
  })
}