Node.js mongoDB Issue with pushing new elements to already existing object

Viewed 56

How do i make it so when i submit to my database it adds it to a object that has the same name? I want it so that when i submit an array on the same date they go under the same object. When I try it automatically adds an object between the parent element and the element I'm adding.

MongoDB adds this object between the elements I want.

I tried looking everywhere but could find any help.

My code:

   app.post('/add-submit', (req,res) => {
    var query = { username: req.body.username };
    db.collection("users").find(query).toArray((err, result) => {
        if (err) throw err;
        console.log(result);
    });
                 
    let postDate = new Date();
    let dd = String(postDate.getDate()).padStart(2, '0');
    let mm = String(postDate.getMonth() + 1).padStart(2, '0');
    let yyyy = postDate.getFullYear();

    postDate = mm + '/' + dd + '/' + yyyy;

    subject = req.body.subject

    pushValue = {"submits": {[postDate]: { [subject] : [ time = req.body.time, description = req.body.description, date = postDate ]}}}

    console.log(pushValue)

    let myquery = { username: req.body.username};
    let newvalues = { $push: pushValue }
    db.collection("users").updateOne(myquery, newvalues, (err, response) => {
        if (err) throw err;
        console.log("1 document updated");
        res.redirect('/users/'+req.body.id)
    });
})

What I'm trying to do:

What I'm trying to do

Thanks.

1 Answers

I try to give a few pointers. Since OP mentioned he is not experienced in that matter, I recommend using the library mongoose. For me, it's the go-to library when working with NodeJS and MongoDB. It's easy to setup and use even for beginners.

Now, to the problem :

Work with multiple Models

Try not to fit everything into one document model. There is a term called 'One-To-Many'-Relationship. And your usecase would be a perfect example for it :

  • A user can me mapped to multiple submits, but one submit can only be mapped to one specific user.
  • Speaking in MongoDB Terms, this would mean, a user has multiple submit entities, and
  • and a submit document has one reference to one user.

How would that look like (using Mongoose) in simplified models


const UserSchema = new Schema ({
  username : String,
  email : String,
  password : String,
  submits: [{ type: Schema.Types.ObjectId, ref: 'Submit', 'default' : [] }],
});

const SubmitSchema = new Schema ({
  date : Date,
  subject : String,
  description : String,
  user : { type: Schema.Types.ObjectId, ref: 'User', 'default' : null }
});

This would result in data looking like this (if using populate)

// retrieve user and all its submits
let user = await User.findById(userid).populate('submits').exec();
console.log( user.submits );
{
  date : "Mon Oct 18 2020 11:36:49",
  subject : "This is the subject",
  description : "This is the description",
  user : "595919bdbcb1b19",
  _id : "5482193857cbc818bc1912"
}, 
{
  date : "Mon Oct 18 2020 11:50:23",
  subject : "This is the subject",
  description : "This is the description",
  user : "595919bdbcb1b19",
  _id : "29299cbca9192bdcabbb"
},
{
  date : "Mon Oct 19 2020 17:24:11",
  subject : "This is the subject",
  description : "This is the description"
  user : "595919bdbcb1b19",
  _id : "5521545b5c5b5aa5125"
},
{
  date : "Mon Oct 20 2020 20:11:57",
  subject : "This is the subject",
  description : "This is the description"
  user : "595919bdbcb1b19",
  _id : "51525235cbba51b15522"
}

These "submit" documents can then be easily sorted by date and or time for example, even client side. This actually also simplifies the structure, you don't need date and time seperate. Also this way it is easier to modify or delete single submits.

You can also query submits directly, like this (simplified)

Something like this would give you all posts for a specific date and specific user :


let submits = await Submit.find({
  user : userid,
  date : new Date('2020-10-19')
}).exec();

Related