[英]MongoDB (Mongoose) update element in array of array
我目前正在使用 node.js express 构建 REST-Api,但无法弄清楚如何更新/添加元素到分数数组。
这是我的 MongoDB 集合中的一个文档(它应该是什么样子):
我的猫鼬模型:
const challengesSchema = new mongoose.Schema({
createdBy:{
type:String,
required: true
},
mapType:{
type:String,
required: true
},
time:{
type:Number,
required: true
},
numberOfMaps:{
type:String,
required: true
},
maps:{
type:Array,
required: true
},
pin:{
type: String,
required: true
},
takenBy:{
type: Array,
required: false
}
})
基本上我收到一个 id,我可以用它来做Challenges.findById({challenge._id})
。 我想出了如何将对象添加到takenBy Array
,如下所示:
Challenges.findOneAndUpdate(
{ _id: challenge._id },
{
$push: {
takenBy: user
}
}
);
如何将元素(分数,如“20”)添加到数组 'takenBy' 中的分数数组?
您可以像这样使用过滤的位置运算符 $一次性推送分数并计算新的 TotalScore。
router.put("/challenges/:id/:scoreId", async (req, res) => {
let score = req.body.score;
try {
let result = await Challenges.findByIdAndUpdate(
req.params.id,
{
$push: { "takenBy.$[inner].scores": score },
$inc: {
"takenBy.$[inner].TotalScore": score
}
},
{
arrayFilters: [{ "inner._id": req.params.scoreId }],
new: true
}
);
if (!result) return res.status(404);
res.send(result);
} catch (err) {
console.log(err);
res.status(500).send("Something went wrong");
}
});
测试:
让我们有这个现有的文件:
{
"_id" : ObjectId("5e08fe4c0bc1b932e8726a0f"),
"maps" : [ ],
"takenBy" : [
{
"_id" : "id1",
"TotalScore" : NumberInt(100),
"scores" : [
NumberInt(20),
NumberInt(60),
NumberInt(20)
]
},
{
"_id" : "id2",
"TotalScore" : NumberInt(30),
"scores" : [
NumberInt(10),
NumberInt(20)
]
}
],
"createdBy" : "5dfe0...",
"mapType" : "World",
"time" : NumberInt(2),
"numberOfMaps" : "2",
"pin" : "9558",
"__v" : NumberInt(0)
}
如果我们想给 id1 添加一个 50 的分数,我们发送一个 PUT 请求( http://..../challenges/5e08fe4c0bc1b932e8726a0f/id1 )和这个主体:
{
"score": 50
}
结果将是这样的:
{
"_id" : ObjectId("5e08fe4c0bc1b932e8726a0f"),
"maps" : [ ],
"takenBy" : [
{
"_id" : "id1",
"TotalScore" : NumberInt(150),
"scores" : [
NumberInt(20),
NumberInt(60),
NumberInt(20),
NumberInt(50)
]
},
{
"_id" : "id2",
"TotalScore" : NumberInt(30),
"scores" : [
NumberInt(10),
NumberInt(20)
]
}
],
"createdBy" : "5dfe0...",
"mapType" : "World",
"time" : NumberInt(2),
"numberOfMaps" : "2",
"pin" : "9558",
"__v" : NumberInt(0)
}
如您所见,分数已添加到相关项目数组中,并且其 TotalScore 也增加了 50,从而使 TotalScore 为 150
...如何更新/添加元素到分数数组。
我会首先检索该数组...推送新值,然后更新。
就像是:
Challenges.findById(challenge._id,(err, db_result) => {
if(err){
console.log(err) // error management
//...
}
if(db_result){
// Get the takenBy array
let takenBy = db_result.takenBy
// Who are we talking about... You need the second _id for that record
let who_id = user._id
let targetIndex = null
let byWho = takenBy.filter((who, index) => {
let gotYa = who._id === who_id
if (gotYa){
targetIndex = index
}
return gotYa // Boolean used as a return for .filter()
})
if(byWho.length>0){
console.log("Got someone... Index: ", targetIndex)
}else{
console.log("No one found?")
return
}
// Push the new value using the index where to update.
takenBy[targetIndex].scores.push(challenge.score)
Challenges.updateOne({_id:challenge._id},{
$set: {
takenBy: takenBy
}
}, (err, data) => {
console.log(data)
}
)
}
});
您可以先检索对象:
const updateChallenge = async (req,res) => {
const challenge = await Challenges.findById(id);
// Then you make duly changes to it with vanilla js:
// Find which element in the array takenBy to update with regular js, methods
like filter work or hardcode it
challenge.takenBy[1].push(newElement);
await challenge.save();
// DONE! :)
}
当然,如果您愿意,您可以使用解构!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.