【发布时间】:2017-12-20 17:59:49
【问题描述】:
我正在尝试实现一个简单的抽奖系统,我在其中执行 GET /test,它返回一个随机用户,该用户 (1) 之前没有赢得抽奖,并且 (2) 在过去一小时内注册。
在 Mongo 中,可能有多个文档与用户关联,因为用户可以注册多个主题。例如{id: 1, name: 'John', subject: 'math',...} 和{id: 1, name: 'John', subject: 'english',...}。如果约翰被选中参加数学抽奖,那么他将没有资格参加随后的所有抽奖活动,因此他无法多次获胜。本质上,抽奖者的 id 必须是唯一的。
我的问题是:我如何执行检查 John 之前是否赢过的逻辑?如果约翰已经赢了,我想从顶部重新启动承诺链并再次执行Math.random,直到选出唯一的赢家。如果没有获胜者符合条件,那么我想返回res.status(500)。
app.get('/test', function(req, res, next) {
var currentTimestamp = new Date()
var oneHourAgo = new Date(currentTimestamp - oneHour)
var query = { "timeStamp": { $lte: currentTimestamp, $gte: oneHourAgo }, "isWinner": false }
var winna = {}
var winnerSelected = false
var collection = db.collection('entries');
while (!winnerSelected) { // how can I do this
collection.find(query).toArray().then( result => {
var winner = result[Math.floor(Math.random() * result.length)];
var query2 = {"id" : winner.id};
winna['id'] = winner.id
winna['name'] = winner.name
winna['subject'] = winner.subject
winna['timeStamp'] = winner.timeStamp
winna['isWinner'] = winner.isWinner
winna['raffleTimestamp'] = winner.raffleTimestamp
return collection.find(query2).toArray();
}).then( result => {
for (var i in result) { // a winner can enter the raffle for multiple subjects, but if he already won once, then I want to redraw by doing a rand function again
if (i.isWinner) { // until a winner who is eligible is found, or if none are eligible, res.status(500)
console.log("i already won")
break
// how do I make it go back to the beginning of the while loop and pick a new random winner?
}
}
console.log("unique winner")
winnerSelected = true // break out of while loop
var query3 = { id: winna.id, subject: winna.subject }
var raffleTimestamp = new Date()
var update = { $set: { isWinner: true, raffleTimestamp: raffleTimestamp } }
winna['isWinner'] = true
winna['raffleTimestamp'] = raffleTimestamp
res.send(winna) // send the winner with the updated fields to clientside
return collection.updateOne(query3, update); // update the isWinner and raffleTimestamp fields
}).then( result => {
res.status(200);
// res.send(result);
}).catch( err => {
console.log(err);
res.status(500);
});
}
})
【问题讨论】:
-
一个想法:如果您更新 所有 获胜者 ID 的记录而不考虑主题,那么原始查询将永远不会返回不合格的记录
-
您认为提供的答案中是否有某些内容无法解决您的问题?如果是这样,请对答案发表评论,以澄清究竟需要解决哪些尚未解决的问题。如果它确实回答了您提出的问题,请注意Accept your Answers您提出的问题
标签: javascript node.js mongodb promise mongodb-query