简体   繁体   中英

What is the proper way to update a deeply nested data on a database

I have the following DB structure :

{
  user: {
    email: "example@email.com",
    days: {
      day1: {
        tasks: {
          task1: {
            name: 'sometask1,
            state: 'false'
          }
          task2: {
            name: 'sometask2,
            state: 'false'
          }
          task3: {
            name: 'sometask3,
            state: 'false'
          }
          ...
        }
        ...
      }
    }
  }
}

My schemas :

// user Schema 

const userSchema = new mongoose.Schema({
  email: String,
  password: String,
  username : String,
  displayUserName : String,
  days : [{
      type : Object,
      ref : Day
   }]
});

// day schema 

const daySchema = new mongoose.Schema({
  dayProgress: Number,
  totalTodos: Number,
  tasks: [{
    type: Object,
    ref: Task,
  }]
});

// task secmea

const taskSchema = new mongoose.Schema({
  taskName: {
    type: String,
    required: true
  },
  taskTiming: {
    type: Date,
    required: true
  },
  taskState: {
    type: Boolean,
    default: false
  },
  taskTypes: {
    type: Object,
    default: {}
  }
});


const User = mongoose.model('User',userSchema)
const Day = mongoose.model('Day',daySchema)
const Task = mongoose.model("Task", taskSchema)

Now let's say a user wants to add a new task ... what is the best way the update the tasks object and prevent the overwriting behavior of the whole array.

What I have tried so far is this ...but it overwrites the whole tasks array :

const task = new Task({
  taskName: 'test',
  taskTiming: new Date(),
  taskState: false,
})

const day = new Day({
  dayProgress: 0,
  totalTodos: 0,
  tasks: task
})

const dayObj = {}
dayObj['day 1'] = day

db.findOneAndUpdate({
  email: 'example@email.com'
}, {
  $set: dayObj
})

what i am getting :

{
  user: {
    email: "example@email.com",
    days: {
      day1: {
        tasks: {
          0: {
            name: 'test',
            state: 'false'
            ...
          }
          // each time i add a task it gets overwritten 
        }
      }
    }
  }
}

what I am looking for :

{
  user: {
    email: "example@email.com",
    days: {
      day1: {
        tasks: {
          test : {
            name: 'test',
            state: 'false'
            ...
          }
          // i can push more tasks here
        }
      }
    }
  }
}

I know I should be pushing values to the tasks array or something like that but I am not really sure how to do it thank you for your time

You can try below query: (Use $push and $ to push to exact location)

db.update({
  _id: ObjectId("5d51bd5ef5fc3d6486b40ffb"),
  "days._id": ObjectId("5d51bd0ff5fc3d6486b40fe4")
}, {
  $push: {'days.$.tasks': taskData}
});

Note:- I have created manually data and tested below query. I have used _id and day._id to find the user and the day where the task needs to push.

Before

{
    "_id" : ObjectId("5d51bd5ef5fc3d6486b40ffb"),
    "email" : "kk@kk.com",
    "username" : "KK_KK",
    "displayUserName" : "KK",
    "days" : [ 
        {
            "_id" : ObjectId("5d51bd0ff5fc3d6486b40fe4"),
            "dayProgress" : 1,
            "totalTodos" : 2,
            "tasks" : [ 
                {
                    "_id" : ObjectId("5d51bcdef5fc3d6486b40fd2"),
                    "taskName" : "ABC",
                    "taskState" : false,
                    "taskTypes" : "NEW"
                }
            ]
        }
    ]
}

After

{
    "_id" : ObjectId("5d51bd5ef5fc3d6486b40ffb"),
    "email" : "kk@kk.com",
    "username" : "KK_KK",
    "displayUserName" : "KK",
    "days" : [ 
        {
            "_id" : ObjectId("5d51bd0ff5fc3d6486b40fe4"),
            "dayProgress" : 1,
            "totalTodos" : 2,
            "tasks" : [ 
                {
                    "_id" : ObjectId("5d51bcdef5fc3d6486b40fd2"),
                    "taskName" : "ABC",
                    "taskState" : false,
                    "taskTypes" : "NEW"
                }, 
                {
                    "taskName" : "ABC1",
                    "taskState" : true,
                    "taskTypes" : "OLD"
                }
            ]
        }
    ]
}

Hope this helps!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM