使用 InsertOne/UpdateOne 在 DB 中添加值 - 如果找到以前的值;返回 NaN 而不是实际数字
Posted
技术标签:
【中文标题】使用 InsertOne/UpdateOne 在 DB 中添加值 - 如果找到以前的值;返回 NaN 而不是实际数字【英文标题】:Using InsertOne/UpdateOne to add value in DB - If previous value found; returns NaN instead of actual number 【发布时间】:2020-12-16 06:01:15 【问题描述】:你好!
我目前正在尝试在我的 DiscordJS 机器人中使用“评分 1-5 星”功能。
我已经到了可以向 OneStar 添加值的地步(使用下图所示的命令)
它按预期向 OneStar 输入,因为这是管理员第一次被评为 1 星。
但是一旦我尝试向另一个对象添加一个值,比如 TwoStar - 它们返回为 NaN。
现在有趣的部分来了。 如果我决定先给 TwoStar 添加一个值(!rate admin @MENIX 2)
因为现在管理员有一个两星评级,它返回一个预期的值 - 但是如果我在添加到 OneStar 之后;那么现在将返回 NaN
这是该位的完整代码:
Functions.js:
AddRating: async function (UserID, toAdd)
const mclient = await MongoClient.connect(url,
useNewUrlParser: true,
useUnifiedTopology: true
).catch(err =>
console.log(err);
);
if (!mclient) return;
try
const db = await mclient.db("DV");
let collection = db.collection("rating")
var res = await collection.find(
id: UserID
).toArray()
if (toAdd === "1")
if (res.length === 0)
await collection.insertOne(
id: UserID,
OneStar: parseInt(1)
)
else
var myquery =
id: UserID
;
var newvalues =
$set:
OneStar: parseInt(res[0].OneStar) + parseInt(1)
;
await collection.updateOne(myquery, newvalues)
if (toAdd === "2")
if (res.length === 0)
await collection.insertOne(
id: UserID,
TwoStar: parseInt(1)
)
else
var myquery =
id: UserID
;
var newvalues =
$set:
TwoStar: parseInt(res[0].TwoStar) + parseInt(1)
;
await collection.updateOne(myquery, newvalues)
if (toAdd === "3")
if (res.length === 0)
await collection.insertOne(
id: UserID,
ThreeStar: parseInt(1)
)
else
var myquery =
id: UserID
;
var newvalues =
$set:
ThreeStar: parseInt(res[0].ThreeStar) + parseInt(1)
;
await collection.updateOne(myquery, newvalues)
if (toAdd === "4")
if (res.length === 0)
await collection.insertOne(
id: UserID,
FourStar: parseInt(1)
)
else
var myquery =
id: UserID
;
var newvalues =
$set:
FourStar: parseInt(res[0].FourStar) + parseInt(1)
;
await collection.updateOne(myquery, newvalues)
if (toAdd === "5")
if (res.length === 0)
await collection.insertOne(
id: UserID,
FiveStar: parseInt(1)
)
else
var myquery =
id: UserID
;
var newvalues =
$set:
FiveStar: parseInt(res[0].FiveStar) + parseInt(1)
;
await collection.updateOne(myquery, newvalues)
catch (err)
return err;
finally
mclient.close();
,
我的想法是 - 我尝试将它们添加为 (Number(toAdd) 而不是 parseInt's - 但基本上不管我做什么,如果数据库中有一个预先存在的值;新的将返回 NaN .. 而不是它应该的实际值。
任何解决此问题的提示或想法将不胜感激。
我对 Mongo 或多或少有一半的新鲜感,但是在搜索了互联网之后 - 我不知道如何解决这个问题。
【问题讨论】:
您可能想查看 mongo 的$inc
运算符,它用作 +,而不是每次都设置值
【参考方案1】:
这是因为您的响应正在检查用户对象,而您不再检查单个值,让我演示一下(我将立即使用失败案例):
var res = await collection.find( id: UserID ).toArray() //res is now an Array [userObj]
if (res.length === 0) //false since there's something in the array
await collection.insertOne(
id: UserID,
OneStar: parseInt(1)
)
else //entering else now
var myquery =
id: UserID
;
var newvalues =
$set:
OneStar: parseInt(res[0].OneStar) //now trying to parse OneStar, this however is undefined => parseInt(undefined) results in NaN
;
await collection.updateOne(myquery, newvalues)
您没有检查现有的评分数量。关于如何解决这个问题,您有两个选项:在创建用户对象时将所有 Ratings 设置为 0,或者添加对 undefined 的检查(也可以在 mongo 中使用 $inc
运算符,而不是每次都设置)。我将向您展示未定义的检查:
var newVals;
if(res[0].OneStar)
newVals = $inc: OneStar: 1 ; //increase by one if already existing
else
newVals = $set: OneStar: 1 ; //set to one if non-existing
除此之外,您的代码可以进行很多优化,因为除了 OneStar/TwoStar 等部分之外,大部分代码看起来都非常相似。您可以将它们保存为字符串并使用括号语法来访问像
这样的属性let star = "OneStar";
res[0][star] ... //same as res[0].OneStar
但这只是一个旁注,我希望你明白一切
【讨论】:
非常感谢您的帮助 - 非常感谢!所以通读一遍,我非常感谢你清理了一些东西。我试图摆弄这些想法 - 但我认为我仍然走错了路。我添加了一点sn-p。我尝试添加一些控制台日志,但似乎代码实际上并没有进入 res[0][star] 位。 (我确实尝试过 (res[0].OneStar) )New code snippet 这可能是什么原因?我想我对这个问题完全视而不见 我认为我已经解决了 - 我继续添加所有 OneStar、TwoStar、ThreeStar 在数据库中创建时默认添加 & 只是决定使用 $inc 将它们从 0 > 开始增加。它似乎正在按我的预期工作,非常感谢您的指导! 没问题!这就是这个网站的目的!以上是关于使用 InsertOne/UpdateOne 在 DB 中添加值 - 如果找到以前的值;返回 NaN 而不是实际数字的主要内容,如果未能解决你的问题,请参考以下文章
在哪里使用 CORBA 以及在哪里使用 SNMP 进行监控?
为啥在使用 unicode 时我不能在 :before :after 内容之后使用空格
在哪里使用 callable 以及在哪里使用 Runnable Interface?
在 Observable RxSwift 中使用 'asPromise()' 可以在 PromiseKit Promise 中使用吗?
可以在 SELECT 查询中使用 IF() 但不能在 UPDATE 中使用
使用 React,在使用 react-transition-group 时,在 StrictMode 中不推荐使用 findDOMNode 作为警告