我做了一个冒险命令,在Mongo数据库中搜索个人资料,然后使用这些信息来计算XP、硬币等。我还使用了其他几个使用数据库的命令,这些命令工作得很好。然而,这个命令一开始很好地找到了正确的文档,但当我试图用调用的文档中的信息填充命令时,它只从数据库中属于我的个人资料的第一个文档中提取信息。所以,每次有人冒险时,它都会根据我的个人资料来计算一切,然后把它添加到正确的个人资料中。因此,他们继续赚取XP和硬币,而不是根据自己的个人资料信息。请参阅下面的代码。
const { SlashCommandBuilder } = require('@discordjs/builders');
const { Collection, MessageActionRow, MessageButton } = require("discord.js");
const econModel = require('../models/econModel');
const humanizeDuration = require('humanize-duration');
const adventureCooldowns = new Collection();
module.exports = {
data: new SlashCommandBuilder()
.setName("adventure")
.setDescription("Explore the world and find treasure"),
execute(interaction){
const Member = interaction.member;
const memberHasAdvCooldown = adventureCooldowns.has(Member.id);
function getRandomInt(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min)) + min;
}
if(memberHasAdvCooldown){
const remaining1 = adventureCooldowns.get(Member.id) - new Date();
const remainingFormatted1 = humanizeDuration(remaining1, {
language: 'en',
round: true,
units: ['h', 'm', 's'],
})
interaction.reply({ content: `You must wait ${remainingFormatted1} for the cooldown period to end before adventuring again.`, ephemeral: true});
}
if(!adventureCooldowns.has(Member.id)){
econModel.findOne({ MemberId: Member.id }, async (err, Account) => {
if(err) throw err;
if(Account) {
console.log(`ID: ${Member.id}\n${Member.nickname}`);
const curXp = Account.Exp;
console.log(`Current XP: ${curXp}`);
const curLvl = Account.Level;
console.log(`Curent Level: ${curLvl}`);
const coinBonus = Account.coinBonus;
console.log(`Coin Bonus: ${coinBonus}`);
const xpBonus = Account.expBonus;
console.log(`XP Bonus: ${xpBonus}`);
const xpBase = Math.floor(Math.random() * 10 + 50);
console.log(`Base XP: ${xpBase}`);
const xpLvlBonus = xpBase * curLvl;
console.log(`lvl XP: ${xpLvlBonus}`);
const xpTotal = Math.floor(xpLvlBonus * xpBonus);
console.log(`Total: ${xpTotal}`);
const Coins = getRandomInt(25, 200);
console.log(`Base coins: ${Coins}`);
const coinAdd = Math.floor(Coins * coinBonus);
console.log(`total coins: ${coinAdd}`);
const nextLvl = (500 * Math.pow(2, curLvl))/2;
console.log(`Next level: ${nextLvl}`);
const newExp = curXp + xpTotal;
if(nextLvl <= newExp){
econModel.collection.updateOne({ MemberID: Member.id }, { $inc: {Level: +1} });
econModel.collection.updateOne({ MemberID: Member.id }, { $inc: {Fowlercoins: +coinAdd} });
econModel.collection.updateOne({ MemberID: Member.id }, { $inc: {Exp: +xpTotal} });
interaction.reply({ content: `${Member.nickname}\nYou have leveled up! You are now level ${Account.Level + 1}!\nYou gained ${xpTotal} experience and found ${coinAdd} coins.`, components: [] });
econModel.collection.updateOne({ MemberID: Member.id }, { $set: {Next: nextLvl} });
adventureCooldowns.set(Member.id, Date.now() + 5000); //5000 is 5 seconds
setTimeout(() => adventureCooldowns.delete(Member.id), 5000);
} else{
econModel.collection.updateOne({ MemberID: Member.id }, { $inc: {Fowlercoins: +coinAdd} });
econModel.collection.updateOne({ MemberID: Member.id }, { $inc: {Exp: +xpTotal} });
interaction.reply({ content: `${Member.nickname}\nYou gained ${xpTotal} experience and found ${coinAdd} coins.`, components: [] })
econModel.collection.updateOne({ MemberID: Member.id }, { $set: {Next: nextLvl} });
adventureCooldowns.set(Member.id, Date.now() + 5000); //5000 is 5 seconds
setTimeout(() => adventureCooldowns.delete(Member.id), 5000);
}
} else{
interaction.reply({ embeds: [new MessageEmbed()
.setTitle("ECONOMY SYSTEM")
.setColor("#3be820")
.setDescription(`${interaction.member.nickname} does not have an account! To create one, use /economy start!`)
.setFooter({ text: 'Rum Bot 1.4.5' })]});
}
})
}
}
}
如您所见,它尝试使用的第一件事是被调用文档中的Account.Exp,但它总是用数据库中的第一个文档填充它。你知道怎么阻止这件事发生吗?我已经努力了一个星期,但还没有取得任何进展。
1条答案
按热度按时间z31licg01#
评论中来自测试的其他信息非常有用,信息量也很大。
听起来,您系统中的实际数据并不是您期望的那样。因此,系统可能运行正常,而意外行为是当前数据的结果。按顺序浏览部分评论将有助于回答这个问题。
我使用了
.count
方法和.findOne()
方法。计票员带回了10份文件,尽管告诉它要找到具有特定ID的那一份这里的“尽管告诉它要找到具有特定ID的那个文档*”的措辞很有趣。
MemberId
字段的econModel
集合中是否有unique index?如果不是,则数据库本身不存在强制执行隐含声明的约束,即应该只有一个文档的MemberId
字段具有给定值。不过,findOne查询的行为有所不同。尽管请求特定的文档(不是集合中的第一个文档),它仍然会返回第一个文档。FindOne查询似乎未正确运行。
为什么你认为
findOne({MemberId: <val>})
的输出是错误的?返回的文档的MemberId
字段的值是否与您查询的值不同?根据您的测试,我的印象是您的
econModel
集合中有10
文档,它们的MemberId
字段的值与您正在搜索的文档相匹配。在接下来的步骤中,我建议检查所有这些值((.find({MemberId: <val>})
),如果它们不是预期的值,则更新值,如果希望数据库在该字段上强制执行唯一性,则在该字段上创建唯一索引。可能还需要仔细检查代码中是否存在最初导致差异的错误(与手动测试相反)。