簡體   English   中英

MongoDB (Mongoose) 更新數組數組中的元素

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM