简体   繁体   中英

Mongoose: How to post into array inside Schema

I have a Company Schema that will hold some data for that company and an array of posts. When a user submits a post I use passport to decode the token and get some user information. Inside that user information there is an object ID which allows me to find the company that the user belongs to.

So now I have found the company that the user belongs to I need to save the submitted post into the board_posts array inside this company

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const BoardPostSchema = new Schema({
    name: {
        type: String
    }
});

const CompanySchema = new Schema({
    company_name: {
        type: String
    },
    board_posts: [BoardPostSchema],
});

module.exports = Company = mongoose.model('companies', CompanySchema);
router.post('/new-opportunity',  passport.authenticate('jwt', { 
    session: false 
}), (req, res) => {
    let user = req.user;
    let newPost = req.body;
    let companyId = user.company_id;

    const boardPost = {
        name: newPost.name
    };

    Company.find({'_id': companyId})
        .then(company => {
            // push boardPost into this company.board_posts array
        })
        .catch(error => {

        });
});

You can use $push and update

router.post('/new-opportunity',  passport.authenticate('jwt', { 
    session: false 
}), (req, res) => {
    let user = req.user;
    let newPost = req.body;
    let companyId = user.company_id;

    const boardPost = {
        name: newPost.name
    };

    Company.update({_id: user.company_id},{
         $push{
             //the things you want to add
         }
    });
});

Hopefully this is what you want to do!

An alternative solution with findByIdAndUpdate:

router.post("/new-opportunity", passport.authenticate("jwt", { session: false }), (req, res) => {
  let user = req.user;
  let newPost = req.body;
  let companyId = user.company_id;

  const boardPost = {
    name: newPost.name,
  };

  Company.findByIdAndUpdate(
    companyId,
    {
      $push: {
        board_posts: boardPost,
      },
    },
    {
      new: true,
    }
  )
    .then((company) => {
      console.log("Updated compay if found:", company);
      res.send(company);
    })
    .catch((error) => {
      console.log(error);
      res.status(500);
    });
});

Or if you want only update status, you can use updateOne :

router.post("/new-opportunity", passport.authenticate("jwt", { session: false }), (req, res) => {
  let user = req.user;
  let newPost = req.body;
  let companyId = user.company_id;

  const boardPost = {
    name: newPost.name,
  };

  Company.updateOne(
    { _id: companyId },
    {
      $push: {
        board_posts: boardPost,
      },
    }
  )
    .then((result) => {
      console.log(result);
      // result.n; // Number of documents matched
      // result.nModified; // Number of documents modified
      res.send(result);
    })
    .catch((error) => {
      console.log(error);
      res.status(500);
    });
});

Yes you can use the $push and findOneAndUpdate operator. It would look nicer if you use the async/await approach.

router.post('/new-opportunity',  passport.authenticate('jwt', { 
   session: false 
}), async (req, res) => {
   let user = req.user;
   let newPost = req.body;
   let companyId = user.company_id;

   const boardPost = {
       name: newPost.name
   };

  let response = await Company.findOneAndUpdate({'_id': companyId}, {
     $push: {
        board_posts: "testword1"
     }
  },{ new: true })  //i set this to true so mongodb will return me the new updated document

  res.send(response);

});

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