0

this is my schema

const mongoose = require('mongoose')

const MaterialListSchema = new mongoose.Schema({
    nomenclature:{
        type: String,
        required: true
    },
    national: {
        type: String,
        required: true
    },
    partnumber:{
        type:String,
        required:true
    },
    quantity: { 
        type: Number,
        required: true
    },
    unit:{
        type: String,
        required: true
    },
    price: {
        type: Number,
        required: true
    }
})

const MrrlSchema = new mongoose.Schema({
    aircrafttype:{
        type: String,
        required: true
    },
    mrrlcategory:{
        type: String,
        required: true
    },
    materiallist: [MaterialListSchema]
})

const Mrrl = mongoose.model('Mrrl', MrrlSchema)

module.exports = Mrrl

this is my update code . but it will delete all the sub document on the selected and will only have remaining

Mrrl.updateOne({
        'materiallist': {$elemMatch: { _id: req.params.id}}
   },{
        $set: { materiallist: req.body }
   }).then((data)=>{
       console.log(data)
   })
大陸北方網友
  • 3,696
  • 3
  • 12
  • 37
Lakay
  • 1

1 Answers1

0

If i understand your question, you need use arrayFilters

  // it is your req.body
  const newMaterial = {
    nomenclature: '2'
  };

  const result = await MrrlSchema.updateMany({ 'materiallist': {$elemMatch: { _id: req.params.id }} },
      { "$set": { "materiallist.$[material]": newMaterial } },
      { "arrayFilters": [ { "material._id": req.params.id } ] });

Note: arrayFilters can be use only with 3.6+ mongo

  • does not work either. and it will add new document rather than update – Lakay Sep 24 '20 at 12:36
  • could you provide your input and expected result please ? – Pavlo Kostohrys Sep 24 '20 at 12:37
  • what is req.body for you ? array? – Pavlo Kostohrys Sep 24 '20 at 13:01
  • { "_id": { "$oid": "5f69698f9ad2e0da5dc5b8e4" }, "aircrafttype": "UH-1H", "mrrlcategory": "STRUCTURAL", "materiallist": [{ "_id": { "$oid": "5f6c919bac3c1e9e7f589aaf" } }, { "_id": { "$oid": "5f6c96d7f2d41aa54a510094" }, "nomenclature": "a", "national": "a", "partnumber": "a", "quantity": 3, "unit": "a", "price": 3 }], "__v": 0 } – Lakay Sep 24 '20 at 13:02
  • and could you please send me two things 1. what is req.body for you 2. what you expect in materiallist after update – Pavlo Kostohrys Sep 24 '20 at 13:03
  • in such case you need use push without each, just $push: { materiallist: req.body }, and req.body will be added to your materiallist – Pavlo Kostohrys Sep 24 '20 at 13:13
  • Not add. the selected sub document must be updated. if I use push then it will add new document – Lakay Sep 24 '20 at 13:15
  • ah , sorry. so i not understand it. You should try use arrayFilter https://docs.mongodb.com/manual/reference/operator/update/positional-filtered/#positional-update-arrayfilters – Pavlo Kostohrys Sep 24 '20 at 13:17
  • ok, i need some time for prepare example for you, will back soon. btw if materiallist is not big array, it can be better just update in nodejs and just do $set , but you must be sure in such case that array will not contain a lot of elements – Pavlo Kostohrys Sep 24 '20 at 13:19
  • yes, but again if you not call this code often , for example customer press button few times per day and your array contain less than 20 elements for example. - It can be better just do with nodejs
      1. Do find 'materiallist': {$elemMatch: { _id: req.params.id}} 2. Do map ( in nodejs ) 3. And do set with new array
    It is not so dramatic for small data
    – Pavlo Kostohrys Sep 24 '20 at 13:34
  • https://stackoverflow.com/questions/26156687/mongoose-find-update-subdocument. this is same with this one – Lakay Sep 24 '20 at 13:52
  • what if I want to delete particular data un subdocument – Lakay Sep 26 '20 at 07:08