[英]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.