Search code examples
javascriptmongodbmongoose

Find and update double nested referenced document


I have 3 models, which are referenced with one another, I want to search for the first document based on a query (this will always exist and return a result), once that returns to search for the second one which is referenced to the first one (which may or may not exist), and push into the 3rd one which is referenced in the 2nd one.

  1. User (Parent Model).
  2. Location (Child of User)
  3. Reports (Child of Location)

I want something similar to the following:

Search User (findById), search for Location using query (search for locationName) - if it exists update it and also push into Reports, else if Location doesn't exist, create one and push into Reports.

Parent Model:

const User = mongoose.model(
  "User",
  new mongoose.Schema({
    firstName: String,
    lastName: String,
    dateOfBirth: Date,
    email: String,
    password: String,
    verified: Boolean,
    locations: [
      {
        type: mongoose.Schema.Types.ObjectId,
        ref: "Locations"
      }
    ]
  })
); 

Child Model:

const Locations = mongoose.model(
  "Locations",
  new mongoose.Schema({
    address: String,
    adress2: String,
    city: String,
    state: String,
    country: String,
    zip: String
    reports: [
      {
        type: mongoose.Schema.Types.ObjectId,
        ref: "Reports"
      }
    ]
  })
);

Child of Child Model:

const Reports = mongoose.model(
  "Reports",
  new mongoose.Schema({
    severity: String,
    note: String,
    date: Date,
  })
);

Any help is greatly appreciated!


Solution

  • I was able to figure this out, by first setting the report values, setting the location values, saving the report, adding the report number to the location value, then searching for a location based on location ID using fineOneAndUpdate:

    Location.findOneAndUpdate(
        { _id: req.body.locationID},
        {
          $push: {
            reports: report
          }
        },
        (err, result) => {
          if (err) {
            res.status(500).send({ message: err });
            return;
          };
    
          if (!result) {
            location.save((err, done) => {
              if (err) {
                res.status(500).send({ message: err });
                return;
              };
              User.findByIdAndUpdate(
                { _id: req.body.id },
                {
                  $push: {
                    locations: done
                  }
                },
                (err, doc) => {
                  if (err) {
                    res.status(500).send({ message: err });
                    return;
                  };
    
                  res.status(200).send({ message: 'Successfully added new location with report.' });
                  return;
                })
            })
          }
    
          if (result) {
            res.status(200).send({ message: 'Successfully updated existing location with report.' });
          }
        }
      );