我运行一个IRC机器人,我有一个函数,从我的Mongodb集合中使用Math.random返回1个随机URL。
我想重构它以返回x个唯一的项目,并且对于url获取命令.getlinks
的每次后续调用,我希望它保持一切唯一,这样用户就不会看到相同的链接除非已经返回所有可能的链接。
我可以使用一些算法或本机mongodb函数吗?
以下是一个示例场景:
我在该系列中共有9条记录。他们有_id
和url
字段。
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
背景资料:
目前我能想到的唯一一件事就是保留所有退回物品的数组,并立即从集合中抓取所有物品并随机获取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(',') );
}
答案 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
})
}